@@ -146,6 +146,53 @@ def valid_prefix_byte(prefix):
146146 return False
147147
148148
149+ def verifying_nkey_to_ed25519 (public_nkey ):
150+ """
151+ :param public_nkey: The public nkey as a bytearray.
152+ :rtype nacl.signing.VerifyKey:
153+ :return: PyNaCl Verifying Key
154+ """
155+ try :
156+ decoded_nkey = base64 .b32decode (public_nkey )
157+ except Exception :
158+ raise ErrInvalidEncoding ()
159+
160+ if len (decoded_nkey ) != 35 :
161+ raise ErrInvalidPublicKey ()
162+
163+ prefix = decoded_nkey [0 ]
164+ if not valid_public_prefix_byte (prefix ):
165+ raise ErrInvalidPrefixByte ()
166+
167+ # the first byte of the base32 decoded nkey is the prefix
168+ # the last two bytes of the base32 decoded nkey is the crc16 checksum
169+ key_without_checksum , checksum = decoded_nkey [:- 2 ], decoded_nkey [- 2 :]
170+
171+ if checksum != crc16_checksum (key_without_checksum ):
172+ raise ErrInvalidCheckSum ()
173+
174+ # remove the nkey prefix to produce the bare ED25519 verifying key
175+ bare_key = key_without_checksum [1 :]
176+ return nacl .signing .VerifyKey (bare_key )
177+
178+
179+ def verify (public_nkey , input , sig ):
180+ """
181+ :param public_nkey: The public nkey as a bytearray.
182+ :param input: The payload in bytes that was signed.
183+ :param sig: The signature in bytes that will be verified.
184+ :rtype bool:
185+ :return: boolean expressing that the signature is valid.
186+ """
187+ vk = verifying_nkey_to_ed25519 (public_nkey )
188+
189+ try :
190+ vk .verify (input , sig )
191+ return True
192+ except nacl .exceptions .BadSignatureError :
193+ raise ErrInvalidSignature ()
194+
195+
149196class KeyPair (object ):
150197
151198 def __init__ (
@@ -189,13 +236,7 @@ def verify(self, input, sig):
189236 :rtype bool:
190237 :return: boolean expressing that the signature is valid.
191238 """
192- kp = self ._keys .verify_key
193-
194- try :
195- kp .verify (input , sig )
196- return True
197- except nacl .exceptions .BadSignatureError :
198- raise ErrInvalidSignature ()
239+ return verify (self .public_key , input , sig )
199240
200241 @property
201242 def public_key (self ):
@@ -217,8 +258,7 @@ def public_key(self):
217258 src .insert (0 , prefix )
218259
219260 # Calculate and include crc16 checksum
220- crc = crc16 (src )
221- crc_bytes = (crc ).to_bytes (2 , byteorder = 'little' )
261+ crc_bytes = crc16_checksum (src )
222262 src .extend (crc_bytes )
223263
224264 # Encode to base32
@@ -236,8 +276,7 @@ def private_key(self):
236276 src .insert (0 , PREFIX_BYTE_PRIVATE )
237277
238278 # Calculate and include crc16 checksum
239- crc = crc16 (src )
240- crc_bytes = (crc ).to_bytes (2 , byteorder = 'little' )
279+ crc_bytes = crc16_checksum (src )
241280 src .extend (crc_bytes )
242281
243282 base32_encoded = base64 .b32encode (src )
@@ -570,6 +609,12 @@ def __str__(self):
570609 return "nkeys: invalid encoded key"
571610
572611
612+ class ErrInvalidCheckSum (NkeysError ):
613+
614+ def __str__ (self ):
615+ return "nkeys: invalid crc16 checksum"
616+
617+
573618class ErrInvalidSignature (NkeysError ):
574619
575620 def __str__ (self ):
0 commit comments