Author | SHA1 | Message | Date |
---|---|---|---|
|
6e623fe12c |
document how to run tests...
This caught a miscompile on FreeBSD that was addressed in
|
2 years ago |
|
1e27007559 | amd64 is the arch name on FreeBSD.. | 2 years ago |
|
9cea5a5d5f | wrap commands with code block, drop make test as missing.. | 2 years ago |
|
0520511b64 | add a couple test vectors from the RFC... | 2 years ago |
|
347057c10b | old versions of clang can only handle a single argument | 2 years ago |
|
c3917f27cb | forgot that FreeBSD's lib format is slightly different, this should work | 2 years ago |
|
048bfefe65 | update to new build infra, python 3, and add instructions.. | 2 years ago |
@@ -97,10 +97,11 @@ See https://www.ristretto.group for details, once that site is up. | |||||
## Build and Install | ## Build and Install | ||||
cmake -DCMAKE_INSTALL_PREFIX=<Install path> <path to root directory> | |||||
make | |||||
make test | |||||
make install | |||||
``` | |||||
cmake -DCMAKE_INSTALL_PREFIX=<Install path> <path to root directory> | |||||
make | |||||
make install | |||||
``` | |||||
Most C source code is generated through a python script during the build. | Most C source code is generated through a python script during the build. | ||||
Some files holding tables are generated in one more step building an | Some files holding tables are generated in one more step building an | ||||
@@ -108,12 +109,16 @@ executable to generate them. They are thus stored in the source tree to help | |||||
cross-compilation. The build script update them when their dependencies | cross-compilation. The build script update them when their dependencies | ||||
are modified, to build only these files: | are modified, to build only these files: | ||||
make decaf_tables | |||||
``` | |||||
make decaf_tables | |||||
``` | |||||
Doxygen generated documentation is located in ./doc directory in the | Doxygen generated documentation is located in ./doc directory in the | ||||
binary tree after running | binary tree after running | ||||
make doc | |||||
``` | |||||
make doc | |||||
``` | |||||
## Licensing | ## Licensing | ||||
@@ -0,0 +1,37 @@ | |||||
Installation | |||||
------------ | |||||
The easiest way to install is to run the command: | |||||
``` | |||||
pip install 'git+https://git.code.sf.net/p/ed448goldilocks/code#egg=edgold&subdirectory=python' | |||||
``` | |||||
After installation, the tests can be run: | |||||
``` | |||||
python -m unittest edgold.ed448 | |||||
``` | |||||
This helps ensure that the correct architecture was detected when | |||||
compiling, and that the code works. It include a couple test vectors | |||||
from the RFC, along with verifying that the code can properly interact | |||||
with the library. | |||||
Usage | |||||
----- | |||||
This wraps the Ed448 code into a simple to use class, EDDSA448. The | |||||
easiest way to geenrate a new key is to use the generate class method. | |||||
Example: | |||||
``` | |||||
from edgold.ed448 import EDDSA448 | |||||
key = EDDSA448.generate() | |||||
privkey = key.export(key('raw') | |||||
msg = b'This is a message to sign' | |||||
sig = key.sign(msg) | |||||
pubkey = key.public_key().export_key('raw') | |||||
key = EDDSA448(pub=pubkey) | |||||
key.verify(sig, msg) | |||||
``` |
@@ -1,6 +1,6 @@ | |||||
#!/usr/bin/env python | #!/usr/bin/env python | ||||
# | # | ||||
# Copyright 2017 John-Mark Gurney. | |||||
# Copyright 2017, 2022 John-Mark Gurney. | |||||
# All rights reserved. | # All rights reserved. | ||||
# | # | ||||
# Redistribution and use in source and binary forms, with or without | # Redistribution and use in source and binary forms, with or without | ||||
@@ -33,10 +33,11 @@ of signing due to the complexity of integration w/ the library, and | |||||
that things should be more simple to use.''' | that things should be more simple to use.''' | ||||
__author__ = 'John-Mark Gurney' | __author__ = 'John-Mark Gurney' | ||||
__copyright__ = 'Copyright 2017 John-Mark Gurney''' | |||||
__license__ = 'BSD' | |||||
__version__ = '0.1' | |||||
__status__ = 'alpha' | |||||
__copyright__ = 'Copyright 2017, 2022 John-Mark Gurney''' | |||||
__license__ = 'BSD-2-Clause' | |||||
__version__ = '1.0' | |||||
__all__ = [ 'EDDSA448', 'generate' ] | |||||
import array | import array | ||||
import os | import os | ||||
@@ -94,13 +95,7 @@ def _makeba(s): | |||||
return r | return r | ||||
def _makestr(a): | def _makestr(a): | ||||
# XXX - because python3 sucks, and unittest doesn't offer | |||||
# ability to silence stupid warnings, hide the tostring | |||||
# DeprecationWarning. | |||||
with warnings.catch_warnings(): | |||||
warnings.simplefilter('ignore') | |||||
return array.array('B', a).tostring() | |||||
return bytes(a) | |||||
def _ed448_privkey(): | def _ed448_privkey(): | ||||
return _makeba(os.urandom(DECAF_EDDSA_448_PRIVATE_BYTES)) | return _makeba(os.urandom(DECAF_EDDSA_448_PRIVATE_BYTES)) | ||||
@@ -286,7 +281,46 @@ class TestEd448(unittest.TestCase): | |||||
# Make sure it fails w/ invalid/different context | # Make sure it fails w/ invalid/different context | ||||
self.assertRaises(ValueError, key.verify, sig, message, ctx + b'a') | self.assertRaises(ValueError, key.verify, sig, message, ctx + b'a') | ||||
# https://www.rfc-editor.org/rfc/rfc8032#section-7.4 | |||||
# secret key, public key, message, context, signature | |||||
_rfc8032testvectors = [ | |||||
('6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b', | |||||
'5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180', | |||||
'', | |||||
'', | |||||
'533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600'), | |||||
('c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e', | |||||
'43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480', | |||||
'03', | |||||
'666f6f', | |||||
'd4f8f6131770dd46f40867d6fd5d5055de43541f8c5e35abbcd001b32a89f7d2151f7647f11d8ca2ae279fb842d607217fce6e042f6815ea000c85741de5c8da1144a6a1aba7f96de42505d7a7298524fda538fccbbb754f578c1cad10d54d0d5428407e85dcbc98a49155c13764e66c3c00'), | |||||
] | |||||
class TestBasicLib(unittest.TestCase): | class TestBasicLib(unittest.TestCase): | ||||
def test_kat(self): | |||||
for idx, (key, pubkey, msg, ctx, checksig) in \ | |||||
enumerate(map(bytes.fromhex, x) for x in | |||||
_rfc8032testvectors): | |||||
with self.subTest(idx=idx): | |||||
priv = _makeba(key) | |||||
pub = ed448_pubkey_t() | |||||
decaf.decaf_ed448_derive_public_key(pub, priv) | |||||
self.assertEqual(pubkey, _makestr(pub)) | |||||
sig = ed448_sig_t() | |||||
if not ctx: | |||||
ctx = None | |||||
ctxargs = EDDSA448._makectxargs(ctx) | |||||
decaf.decaf_ed448_sign(sig, priv, pub, _makeba(msg), len(msg), 0, *ctxargs) | |||||
self.assertEqual(checksig, _makestr(sig)) | |||||
r = decaf.decaf_ed448_verify(sig, pub, _makeba(msg), len(msg), 0, *ctxargs) | |||||
self.assertTrue(r) | |||||
def test_basic(self): | def test_basic(self): | ||||
priv = _ed448_privkey() | priv = _ed448_privkey() | ||||
pub = ed448_pubkey_t() | pub = ed448_pubkey_t() | ||||
@@ -4,19 +4,33 @@ from distutils.command.build import build | |||||
from distutils.core import setup | from distutils.core import setup | ||||
import os | import os | ||||
import sys | |||||
def libname(ver): | |||||
vars = dict( | |||||
name='libdecaf', | |||||
ver=ver, | |||||
) | |||||
if sys.platform == 'darwin': | |||||
return '%(name)s.%(ver)d.dylib' % vars | |||||
return '%(name)s.so.%(ver)d' % vars | |||||
class my_build(build): | class my_build(build): | ||||
def run(self): | def run(self): | ||||
build.run(self) | build.run(self) | ||||
if not self.dry_run: | if not self.dry_run: | ||||
os.spawnlp(os.P_WAIT, 'sh', 'sh', '-c', 'cd .. && gmake lib') | |||||
self.copy_file(os.path.join('..', 'build', 'lib', 'libdecaf.so'), os.path.join(self.build_lib, 'edgold')) | |||||
os.spawnlp(os.P_WAIT, 'sh', 'sh', '-c', | |||||
'cd .. && mkdir build && cd build && cmake .. && make') | |||||
self.copy_file(os.path.join('..', 'build', 'src', libname(0)), | |||||
os.path.join(self.build_lib, 'edgold', 'libdecaf.so')) | |||||
cmdclass = {} | cmdclass = {} | ||||
cmdclass['build'] = my_build | cmdclass['build'] = my_build | ||||
setup(name='edgold', | setup(name='edgold', | ||||
version='0.1', | |||||
version='1.0', | |||||
description='The Ed ECC Goldilocks Python wrapper', | description='The Ed ECC Goldilocks Python wrapper', | ||||
author='John-Mark Gurney', | author='John-Mark Gurney', | ||||
author_email='jmg@funkthat.com', | author_email='jmg@funkthat.com', | ||||
@@ -42,7 +42,7 @@ if(MSVC)# On MSVC Windows, Processor is always AMD64 on both platforms (x86/x64) | |||||
else() | else() | ||||
set(MSVC_ARCH ${CMAKE_SYSTEM_PROCESSOR})# just to have a value | set(MSVC_ARCH ${CMAKE_SYSTEM_PROCESSOR})# just to have a value | ||||
endif() | endif() | ||||
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64" AND NOT MSVC)#Decaf doesn't support 64bits on MSVC yet | |||||
if((${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "amd64") AND NOT MSVC)#Decaf doesn't support 64bits on MSVC yet | |||||
message("Target architecture is x86_64") | message("Target architecture is x86_64") | ||||
set(TARGET_ARCH_DIR arch_x86_64) | set(TARGET_ARCH_DIR arch_x86_64) | ||||
set(TARGET_ARCH_DIR_P25519 arch_x86_64) | set(TARGET_ARCH_DIR_P25519 arch_x86_64) | ||||
@@ -143,8 +143,7 @@ void DECAF_API_VIS decaf_ed$(gf_shortname)_sign ( | |||||
uint8_t context_len | uint8_t context_len | ||||
) __attribute__((nonnull(1,2,3))) DECAF_NOINLINE | ) __attribute__((nonnull(1,2,3))) DECAF_NOINLINE | ||||
#if DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED | #if DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED | ||||
__attribute__((deprecated("Passing the pubkey and privkey separately is unsafe", | |||||
"decaf_ed$(gf_shortname)_keypair_sign"))) | |||||
__attribute__((deprecated("Passing the pubkey and privkey separately is unsafe decaf_ed$(gf_shortname)_keypair_sign"))) | |||||
#endif | #endif | ||||
; | ; | ||||
@@ -171,8 +170,7 @@ void DECAF_API_VIS decaf_ed$(gf_shortname)_sign_prehash ( | |||||
uint8_t context_len | uint8_t context_len | ||||
) __attribute__((nonnull(1,2,3,4))) DECAF_NOINLINE | ) __attribute__((nonnull(1,2,3,4))) DECAF_NOINLINE | ||||
#if DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED | #if DECAF_EDDSA_NON_KEYPAIR_API_IS_DEPRECATED | ||||
__attribute__((deprecated("Passing the pubkey and privkey separately is unsafe", | |||||
"decaf_ed$(gf_shortname)_keypair_sign_prehash"))) | |||||
__attribute__((deprecated("Passing the pubkey and privkey separately is unsafe decaf_ed$(gf_shortname)_keypair_sign_prehash"))) | |||||
#endif | #endif | ||||
; | ; | ||||