114 lines
3.5 KiB
Go
114 lines
3.5 KiB
Go
|
|
// 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
|
|
}
|
|
|
|
|
|
|