From a2e05e6f3dcd815daa44f64e2ced54baffeb0c1f Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 4 May 2025 19:24:27 -0300 Subject: [PATCH] nip44: simplify slightly. --- nip44/nip44.go | 22 ++++++++++------------ nip44/nip44_test.go | 45 --------------------------------------------- 2 files changed, 10 insertions(+), 57 deletions(-) diff --git a/nip44/nip44.go b/nip44/nip44.go index b29506b..6ca0f3a 100644 --- a/nip44/nip44.go +++ b/nip44/nip44.go @@ -22,7 +22,6 @@ import ( const version byte = 2 const ( - MinPlaintextSize = 0x0001 // 1b msg => padded to 32b MaxPlaintextSize = 0xffff // 65535 (64kb-1) => padded to 64kb ) @@ -59,14 +58,14 @@ func Encrypt(plaintext string, conversationKey [32]byte, applyOptions ...func(op } } - cc20key, cc20nonce, hmackey, err := messageKeys(conversationKey, nonce) + cc20key, cc20nonce, hmacKey, err := messageKeys(conversationKey, nonce) if err != nil { return "", err } plain := []byte(plaintext) size := len(plain) - if size < MinPlaintextSize || size > MaxPlaintextSize { + if size == 0 || size > MaxPlaintextSize { return "", fmt.Errorf("plaintext should be between 1b and 64kB") } @@ -80,7 +79,7 @@ func Encrypt(plaintext string, conversationKey [32]byte, applyOptions ...func(op return "", err } - mac, err := sha256Hmac(hmackey, ciphertext, nonce) + mac, err := sha256Hmac(hmacKey, ciphertext, nonce) if err != nil { return "", err } @@ -97,7 +96,7 @@ func Encrypt(plaintext string, conversationKey [32]byte, applyOptions ...func(op func Decrypt(b64ciphertextWrapped string, conversationKey [32]byte) (string, error) { cLen := len(b64ciphertextWrapped) if cLen < 132 || cLen > 87472 { - return "", fmt.Errorf(fmt.Sprintf("invalid payload length: %d", cLen)) + return "", fmt.Errorf("invalid payload length: %d", cLen) } if b64ciphertextWrapped[0:1] == "#" { return "", fmt.Errorf("unknown version") @@ -109,24 +108,24 @@ func Decrypt(b64ciphertextWrapped string, conversationKey [32]byte) (string, err } if decoded[0] != version { - return "", fmt.Errorf(fmt.Sprintf("unknown version %d", decoded[0])) + return "", fmt.Errorf("unknown version %d", decoded[0]) } dLen := len(decoded) if dLen < 99 || dLen > 65603 { - return "", fmt.Errorf(fmt.Sprintf("invalid data length: %d", dLen)) + return "", fmt.Errorf("invalid data length: %d", dLen) } var nonce [32]byte copy(nonce[:], decoded[1:33]) ciphertext := decoded[33 : dLen-32] givenMac := decoded[dLen-32:] - cc20key, cc20nonce, hmackey, err := messageKeys(conversationKey, nonce) + cc20key, cc20nonce, hmacKey, err := messageKeys(conversationKey, nonce) if err != nil { return "", err } - expectedMac, err := sha256Hmac(hmackey, ciphertext, nonce) + expectedMac, err := sha256Hmac(hmacKey, ciphertext, nonce) if err != nil { return "", err } @@ -141,8 +140,7 @@ func Decrypt(b64ciphertextWrapped string, conversationKey [32]byte) (string, err } unpaddedLen := binary.BigEndian.Uint16(padded[0:2]) - if unpaddedLen < uint16(MinPlaintextSize) || unpaddedLen > uint16(MaxPlaintextSize) || - len(padded) != 2+calcPadding(int(unpaddedLen)) { + if unpaddedLen == 0 || unpaddedLen > MaxPlaintextSize || len(padded) != 2+calcPadding(int(unpaddedLen)) { return "", fmt.Errorf("invalid padding") } @@ -160,7 +158,7 @@ func GenerateConversationKey(pub nostr.PubKey, sk [32]byte) ([32]byte, error) { var ck [32]byte if bytes.Compare(sk[:], maxThreshold) != -1 || sk == [32]byte{} { - return ck, fmt.Errorf("invalid private key: x coordinate %s is not on the secp256k1 curve", sk) + return ck, fmt.Errorf("invalid private key: x coordinate %x is not on the secp256k1 curve", sk) } shared, err := computeSharedSecret(pub, sk) diff --git a/nip44/nip44_test.go b/nip44/nip44_test.go index 4755af7..7fdfe99 100644 --- a/nip44/nip44_test.go +++ b/nip44/nip44_test.go @@ -1,11 +1,8 @@ package nip44 import ( - "crypto/rand" "crypto/sha256" "encoding/hex" - "fmt" - "strings" "testing" "fiatjaf.com/nostr" @@ -1072,48 +1069,6 @@ func TestMessageKeyGeneration033(t *testing.T) { ) } -func TestMaxLength(t *testing.T) { - sk1 := nostr.GeneratePrivateKey() - sk2 := nostr.GeneratePrivateKey() - pub2 := nostr.GetPublicKey(sk2) - salt := make([]byte, 32) - rand.Read(salt) - conversationKey, _ := GenerateConversationKey(pub2, sk1) - plaintext := strings.Repeat("a", MaxPlaintextSize) - encrypted, err := Encrypt(plaintext, conversationKey, WithCustomNonce(salt)) - if err != nil { - t.Error(err) - } - - assertCryptPub(t, - hex.EncodeToString(sk1[:]), - hex.EncodeToString(pub2[:]), - fmt.Sprintf("%x", conversationKey), - fmt.Sprintf("%x", salt), - plaintext, - encrypted, - ) -} - -func assertCryptPub(t *testing.T, sk1 string, pub2 string, conversationKey string, customNonce string, plaintext string, expected string) { - k1, err := hexDecode32Array(conversationKey) - require.NoErrorf(t, err, "hex decode failed for conversation key: %v", err) - - assertConversationKeyGenerationPub(t, sk1, pub2, conversationKey) - - s, err := hex.DecodeString(customNonce) - require.NoErrorf(t, err, "hex decode failed for salt: %v", err) - - actual, err := Encrypt(plaintext, k1, WithCustomNonce(s)) - require.NoError(t, err, "encryption failed: %v", err) - require.Equalf(t, expected, actual, "wrong encryption") - - decrypted, err := Decrypt(expected, k1) - require.NoErrorf(t, err, "decryption failed: %v", err) - - require.Equal(t, decrypted, plaintext, "wrong decryption") -} - func hexDecode32Array(hexString string) (res [32]byte, err error) { _, err = hex.Decode(res[:], []byte(hexString)) return res, err