seekia/internal/memos/createMemos/createMemos.go

115 lines
3.5 KiB
Go
Raw Normal View History

// createMemos provides a function to create Seekia memos
// Memos are specially formatted messages that are signed with a Seekia identity key
// They can be shared anywhere, and verified using the Seekia application
package createMemos
import "seekia/internal/allowedText"
import "seekia/internal/cryptography/blake3"
import "seekia/internal/cryptography/edwardsKeys"
import "seekia/internal/encoding"
import "seekia/internal/identity"
import "strings"
import "errors"
//Outputs:
// -string: Memo
// -error
func CreateMemo(identityPublicKey [32]byte, identityPrivateKey [64]byte, identityType string, decorativePrefix string, decorativeSuffix string, memoMessage string)(string, error){
authorIdentityHash, err := identity.ConvertIdentityKeyToIdentityHash(identityPublicKey, identityType)
if (err != nil) { return "", err }
authorIdentityHashString, _, err := identity.EncodeIdentityHashBytesToString(authorIdentityHash)
if (err != nil) { return "", err }
textIsAllowed := allowedText.VerifyStringIsAllowed(memoMessage)
if (textIsAllowed == false){
return "", errors.New("CreateMemo called with unallowed text.")
}
if (len(memoMessage) > 50000){
return "", errors.New("CreateMemo called with memoMessage that is too long")
}
identityPublicKeyHex := encoding.EncodeBytesToHexString(identityPublicKey[:])
identityPublicKeyPieceA := identityPublicKeyHex[:32]
identityPublicKeyPieceB := identityPublicKeyHex[32:]
// We use this to build the memo body
var memoBodyBuilder strings.Builder
memoBodyBuilder.WriteString("|- Identity Key:\n")
memoBodyBuilder.WriteString("| " + identityPublicKeyPieceA + "\n")
memoBodyBuilder.WriteString("| " + identityPublicKeyPieceB + "\n")
memoBodyBuilder.WriteString("|\n")
memoBodyBuilder.WriteString("|- Author:\n")
memoBodyBuilder.WriteString("| " + authorIdentityHashString + "\n")
memoBodyBuilder.WriteString("|\n")
memoBodyBuilder.WriteString("|- Memo:\n")
memoBodyBuilder.WriteString("|\n")
memoMessageLinesList := strings.Split(memoMessage, "\n")
for _, messageLine := range memoMessageLinesList{
if (messageLine == ""){
// There is no content on this line. It only contains a newline.
memoLine := "|\n"
memoBodyBuilder.WriteString(memoLine)
} else {
memoLine := "| " + messageLine + "\n"
memoBodyBuilder.WriteString(memoLine)
}
}
memoBodyBuilder.WriteString("|\n")
// The memo body is the part of the memo we will sign with the author's identity key
memoBody := memoBodyBuilder.String()
memoBodyBytes := []byte(memoBody)
memoBodyHash, err := blake3.Get32ByteBlake3Hash(memoBodyBytes)
if (err != nil) { return "", err }
signatureBytes := edwardsKeys.CreateSignature(identityPrivateKey, memoBodyHash)
signatureString := encoding.EncodeBytesToBase64String(signatureBytes[:])
signaturePiece1 := signatureString[:30]
signaturePiece2 := signatureString[30:60]
signaturePiece3 := signatureString[60:]
// We use this to build the memo header
var memoHeaderBuilder strings.Builder
memoHeaderBuilder.WriteString("| " + decorativePrefix + " Seekia Memo " + decorativeSuffix + "\n")
memoHeaderBuilder.WriteString("|\n")
memoHeaderBuilder.WriteString("|- Signature:\n")
memoHeaderBuilder.WriteString("| " + signaturePiece1 + "\n")
memoHeaderBuilder.WriteString("| " + signaturePiece2 + "\n")
memoHeaderBuilder.WriteString("| " + signaturePiece3 + "\n")
memoHeaderBuilder.WriteString("|\n")
memoHeader := memoHeaderBuilder.String()
memoFooter := "| " + decorativePrefix + " End Of Memo " + decorativeSuffix
newMemo := memoHeader + memoBody + memoFooter
return newMemo, nil
}