Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC: Add hazmat module (exposing scalar, point) #1635

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add "hazmat" module which exposes low-level primitives (scalar, point)
theStack committed Nov 8, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 1123e352be6a9474df4feda1a6bbbc003cbea1ae
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -62,9 +62,14 @@ option(SECP256K1_ENABLE_MODULE_EXTRAKEYS "Enable extrakeys module." ON)
option(SECP256K1_ENABLE_MODULE_SCHNORRSIG "Enable schnorrsig module." ON)
option(SECP256K1_ENABLE_MODULE_MUSIG "Enable musig module." ON)
option(SECP256K1_ENABLE_MODULE_ELLSWIFT "Enable ElligatorSwift module." ON)
option(SECP256K1_ENABLE_MODULE_HAZMAT "Enable hazmat module." OFF)

# Processing must be done in a topological sorting of the dependency graph
# (dependent module first).
if(SECP256K1_ENABLE_MODULE_HAZMAT)
add_compile_definitions(ENABLE_MODULE_HAZMAT=1)
endif()

if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
add_compile_definitions(ENABLE_MODULE_ELLSWIFT=1)
endif()
@@ -327,6 +332,7 @@ message(" extrakeys ........................... ${SECP256K1_ENABLE_MODULE_EXTRA
message(" schnorrsig .......................... ${SECP256K1_ENABLE_MODULE_SCHNORRSIG}")
message(" musig ............................... ${SECP256K1_ENABLE_MODULE_MUSIG}")
message(" ElligatorSwift ...................... ${SECP256K1_ENABLE_MODULE_ELLSWIFT}")
message(" hazmat .............................. ${SECP256K1_ENABLE_MODULE_HAZMAT}")
message("Parameters:")
message(" ecmult window size .................. ${SECP256K1_ECMULT_WINDOW_SIZE}")
message(" ecmult gen table size ............... ${SECP256K1_ECMULT_GEN_KB} KiB")
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -300,3 +300,7 @@ endif
if ENABLE_MODULE_ELLSWIFT
include src/modules/ellswift/Makefile.am.include
endif

if ENABLE_MODULE_HAZMAT
include src/modules/hazmat/Makefile.am.include
endif
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -192,6 +192,10 @@ AC_ARG_ENABLE(module_ellswift,
AS_HELP_STRING([--enable-module-ellswift],[enable ElligatorSwift module [default=yes]]), [],
[SECP_SET_DEFAULT([enable_module_ellswift], [yes], [yes])])

AC_ARG_ENABLE(module_hazmat,
AS_HELP_STRING([--enable-module-hazmat],[enable hazmat module [default=no]]), [],
[SECP_SET_DEFAULT([enable_module_hazmat], [no], [yes])])

AC_ARG_ENABLE(external_default_callbacks,
AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions [default=no]]), [],
[SECP_SET_DEFAULT([enable_external_default_callbacks], [no], [no])])
@@ -430,6 +434,10 @@ if test x"$enable_module_ecdh" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_ECDH=1"
fi

if test x"$enable_module_hazmat" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DENABLE_MODULE_HAZMAT=1"
fi

if test x"$enable_external_default_callbacks" = x"yes"; then
SECP_CONFIG_DEFINES="$SECP_CONFIG_DEFINES -DUSE_EXTERNAL_DEFAULT_CALLBACKS=1"
fi
@@ -463,6 +471,7 @@ AM_CONDITIONAL([ENABLE_MODULE_EXTRAKEYS], [test x"$enable_module_extrakeys" = x"
AM_CONDITIONAL([ENABLE_MODULE_SCHNORRSIG], [test x"$enable_module_schnorrsig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_MUSIG], [test x"$enable_module_musig" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_ELLSWIFT], [test x"$enable_module_ellswift" = x"yes"])
AM_CONDITIONAL([ENABLE_MODULE_HAZMAT], [test x"$enable_module_hazmat" = x"yes"])
AM_CONDITIONAL([USE_EXTERNAL_ASM], [test x"$enable_external_asm" = x"yes"])
AM_CONDITIONAL([USE_ASM_ARM], [test x"$set_asm" = x"arm32"])
AM_CONDITIONAL([BUILD_WINDOWS], [test "$build_windows" = "yes"])
@@ -486,6 +495,7 @@ echo " module extrakeys = $enable_module_extrakeys"
echo " module schnorrsig = $enable_module_schnorrsig"
echo " module musig = $enable_module_musig"
echo " module ellswift = $enable_module_ellswift"
echo " module hazmat = $enable_module_hazmat"
echo
echo " asm = $set_asm"
echo " ecmult window size = $set_ecmult_window"
54 changes: 54 additions & 0 deletions include/secp256k1_hazmat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef SECP256K1_HAZMAT_H
#define SECP256K1_HAZMAT_H

#include "secp256k1.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

/* This module provides low-level cryptographic primitives of secp256k1.
* Note that these can be used incorrectly and require an in-depth knowledge
* of the cryptographic concepts at work, therefore we call this the
* "hazardous materials" library or "hazmat" for short.
*/

/* Scalar */
typedef union {
unsigned char data[32];
uint64_t align8; /* ensure alignment on 8-bytes boundaries */
} secp256k1_hazmat_scalar;

SECP256K1_API int secp256k1_hazmat_scalar_parse(secp256k1_hazmat_scalar *s, const unsigned char *bin32);
SECP256K1_API void secp256k1_hazmat_scalar_serialize(unsigned char *bin32, const secp256k1_hazmat_scalar *s);
SECP256K1_API void secp256k1_hazmat_scalar_set_zero(secp256k1_hazmat_scalar *s);
SECP256K1_API int secp256k1_hazmat_scalar_is_zero(const secp256k1_hazmat_scalar *s);
SECP256K1_API void secp256k1_hazmat_scalar_add(secp256k1_hazmat_scalar *sres, const secp256k1_hazmat_scalar *s1, const secp256k1_hazmat_scalar *s2);
SECP256K1_API void secp256k1_hazmat_scalar_mul(secp256k1_hazmat_scalar *sres, const secp256k1_hazmat_scalar *s1, const secp256k1_hazmat_scalar *s2);
SECP256K1_API void secp256k1_hazmat_scalar_negate(secp256k1_hazmat_scalar *s);

/* Point */
typedef union {
unsigned char data[160];
uint64_t align8; /* ensure alignment on 8-bytes boundaries */
} secp256k1_hazmat_point;

SECP256K1_API int secp256k1_hazmat_point_parse(secp256k1_hazmat_point *p, const unsigned char *pubkey33);
SECP256K1_API void secp256k1_hazmat_point_serialize(unsigned char *pubkey33, secp256k1_hazmat_point *p);
SECP256K1_API void secp256k1_hazmat_point_set_infinity(secp256k1_hazmat_point *p);
SECP256K1_API int secp256k1_hazmat_point_is_infinity(const secp256k1_hazmat_point *p);
SECP256K1_API void secp256k1_hazmat_point_add(secp256k1_hazmat_point *pres, secp256k1_hazmat_point *p1, secp256k1_hazmat_point *p2);
SECP256K1_API void secp256k1_hazmat_point_negate(secp256k1_hazmat_point *p);
SECP256K1_API int secp256k1_hazmat_point_equal(const secp256k1_hazmat_point *p1, const secp256k1_hazmat_point *p2);

/* Point multiplication */
SECP256K1_API void secp256k1_hazmat_multiply_with_generator(const secp256k1_context *ctx, secp256k1_hazmat_point *pres, const secp256k1_hazmat_scalar *s);
SECP256K1_API void secp256k1_hazmat_multiply_with_point(secp256k1_hazmat_point *pres, const secp256k1_hazmat_scalar *s, secp256k1_hazmat_point *p);

#ifdef __cplusplus
}
#endif

#endif /* SECP256K1_HAZMAT_H */
3 changes: 3 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -138,6 +138,9 @@ if(SECP256K1_INSTALL)
if(SECP256K1_ENABLE_MODULE_ELLSWIFT)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_ellswift.h")
endif()
if(SECP256K1_ENABLE_MODULE_HAZMAT)
list(APPEND ${PROJECT_NAME}_headers "${PROJECT_SOURCE_DIR}/include/secp256k1_hazmat.h")
endif()
install(FILES ${${PROJECT_NAME}_headers}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
2 changes: 2 additions & 0 deletions src/modules/hazmat/Makefile.am.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include_HEADERS += include/secp256k1_hazmat.h
noinst_HEADERS += src/modules/hazmat/main_impl.h
147 changes: 147 additions & 0 deletions src/modules/hazmat/main_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/***********************************************************************
* Distributed under the MIT software license, see the accompanying *
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
***********************************************************************/

#ifndef SECP256K1_MODULE_HAZMAT_MAIN_H
#define SECP256K1_MODULE_HAZMAT_MAIN_H

#include "../../../include/secp256k1.h"
#include "../../../include/secp256k1_hazmat.h"
#include "../../scalar.h"
#include "../../group.h"
#include "../../eckey.h"
#include "../../ecmult_const.h"

typedef struct {
secp256k1_gej gej;
int z_is_one; /* set if z == 1, i.e. gej can be converted to ge trivially by assigning x/y */
} secp256k1_hazmat_point_struct;

/* Verify that the opaque data types are large enough to hold the underlying structures
(note that this function is never called at run-time and only exists since the STATIC_ASSERT
macro can only be used inside of functions) */
static void secp256k1_hazmat_assertions(void) {
STATIC_ASSERT(sizeof(secp256k1_hazmat_scalar) >= sizeof(secp256k1_scalar));
STATIC_ASSERT(sizeof(secp256k1_hazmat_point) >= sizeof(secp256k1_hazmat_point_struct));
}

int secp256k1_hazmat_scalar_parse(secp256k1_hazmat_scalar *s, const unsigned char *bin32) {
int overflow;
secp256k1_scalar_set_b32((secp256k1_scalar*)s, bin32, &overflow);
return !overflow;
}

void secp256k1_hazmat_scalar_serialize(unsigned char *bin32, const secp256k1_hazmat_scalar *s) {
secp256k1_scalar_get_b32(bin32, (secp256k1_scalar*)s);
}

void secp256k1_hazmat_scalar_set_zero(secp256k1_hazmat_scalar *s) {
*((secp256k1_scalar*)s) = secp256k1_scalar_zero;
}

int secp256k1_hazmat_scalar_is_zero(const secp256k1_hazmat_scalar *s) {
return secp256k1_scalar_is_zero((secp256k1_scalar*)s);
}

void secp256k1_hazmat_scalar_add(secp256k1_hazmat_scalar *sres, const secp256k1_hazmat_scalar *s1, const secp256k1_hazmat_scalar *s2) {
secp256k1_scalar_add((secp256k1_scalar*)sres, (secp256k1_scalar*)s1, (secp256k1_scalar*)s2);
}

void secp256k1_hazmat_scalar_mul(secp256k1_hazmat_scalar *sres, const secp256k1_hazmat_scalar *s1, const secp256k1_hazmat_scalar *s2) {
secp256k1_scalar_mul((secp256k1_scalar*)sres, (secp256k1_scalar*)s1, (secp256k1_scalar*)s2);
}

void secp256k1_hazmat_scalar_negate(secp256k1_hazmat_scalar *s) {
secp256k1_scalar_negate((secp256k1_scalar*)s, (secp256k1_scalar*)s);
}

static void secp256k1_hazmat_point_to_ge(secp256k1_ge *ge, secp256k1_hazmat_point_struct *p) {
if (p->z_is_one) {
secp256k1_ge_set_xy(ge, &p->gej.x, &p->gej.y);
} else {
secp256k1_ge_set_gej(ge, &p->gej);
p->z_is_one = 1;
}
}

int secp256k1_hazmat_point_parse(secp256k1_hazmat_point *p, const unsigned char *pubkey33) {
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;
secp256k1_ge ge;

if (!secp256k1_eckey_pubkey_parse(&ge, pubkey33, 33)) {
return 0;
}
secp256k1_gej_set_ge(&ps->gej, &ge);
ps->z_is_one = 1;
return 1;
}

void secp256k1_hazmat_point_serialize(unsigned char *pubkey33, secp256k1_hazmat_point *p) {
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;
secp256k1_ge ge;
size_t size;
int ret;

secp256k1_hazmat_point_to_ge(&ge, ps);
ret = secp256k1_eckey_pubkey_serialize(&ge, pubkey33, &size, 1);
VERIFY_CHECK(ret == 1 && size == 33);
(void)ret;
}

void secp256k1_hazmat_point_set_infinity(secp256k1_hazmat_point *p) {
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;

secp256k1_gej_set_infinity(&ps->gej);
ps->z_is_one = 0;
}

int secp256k1_hazmat_point_is_infinity(const secp256k1_hazmat_point *p) {
const secp256k1_hazmat_point_struct *ps = (const secp256k1_hazmat_point_struct*)p;

return secp256k1_gej_is_infinity(&ps->gej);
}

void secp256k1_hazmat_point_add(secp256k1_hazmat_point *pres, secp256k1_hazmat_point *p1, secp256k1_hazmat_point *p2) {
secp256k1_hazmat_point_struct *press = (secp256k1_hazmat_point_struct*)pres;
secp256k1_hazmat_point_struct *p1s = (secp256k1_hazmat_point_struct*)p1;
secp256k1_hazmat_point_struct *p2s = (secp256k1_hazmat_point_struct*)p2;
secp256k1_ge ge;

secp256k1_hazmat_point_to_ge(&ge, p2s);
secp256k1_gej_add_ge(&press->gej, &p1s->gej, &ge);
press->z_is_one = 0;
}

void secp256k1_hazmat_point_negate(secp256k1_hazmat_point *p) {
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;

secp256k1_gej_neg(&ps->gej, &ps->gej);
/* negation only changes y; z is untouched, so no update of z_is_one is needed */
}

int secp256k1_hazmat_point_equal(const secp256k1_hazmat_point *p1, const secp256k1_hazmat_point *p2) {
const secp256k1_hazmat_point_struct *p1s = (secp256k1_hazmat_point_struct*)p1;
const secp256k1_hazmat_point_struct *p2s = (secp256k1_hazmat_point_struct*)p2;

return secp256k1_gej_eq_var(&p1s->gej, &p2s->gej);
}

void secp256k1_hazmat_multiply_with_generator(const secp256k1_context *ctx, secp256k1_hazmat_point *p, const secp256k1_hazmat_scalar *s) {
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;

secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &ps->gej, (secp256k1_scalar*)s);
ps->z_is_one = 0;
}

void secp256k1_hazmat_multiply_with_point(secp256k1_hazmat_point *pres, const secp256k1_hazmat_scalar *s, secp256k1_hazmat_point *p) {
secp256k1_hazmat_point_struct *press = (secp256k1_hazmat_point_struct*)pres;
secp256k1_hazmat_point_struct *ps = (secp256k1_hazmat_point_struct*)p;
secp256k1_ge ge;

secp256k1_hazmat_point_to_ge(&ge, ps);
secp256k1_ecmult_const(&press->gej, &ge, (secp256k1_scalar*)s);
press->z_is_one = 0;
}

#endif
4 changes: 4 additions & 0 deletions src/secp256k1.c
Original file line number Diff line number Diff line change
@@ -829,3 +829,7 @@ int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32,
#ifdef ENABLE_MODULE_ELLSWIFT
# include "modules/ellswift/main_impl.h"
#endif

#ifdef ENABLE_MODULE_HAZMAT
# include "modules/hazmat/main_impl.h"
#endif