Skip to content

Commit

Permalink
Add "hazmat" module which exposes low-level primitives (scalar, point)
Browse files Browse the repository at this point in the history
  • Loading branch information
theStack committed Nov 8, 2024
1 parent 8deef00 commit 3099dfc
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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")
Expand Down
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
52 changes: 52 additions & 0 deletions include/secp256k1_hazmat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef SECP256K1_HAZMAT_H
#define SECP256K1_HAZMAT_H

#include "secp256k1.h"

#ifdef __cplusplus
extern "C" {
#endif

/* 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
Expand Up @@ -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}
)
Expand Down
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
Expand Up @@ -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

0 comments on commit 3099dfc

Please sign in to comment.