iPXE
weierstrass.c File Reference

Weierstrass elliptic curves. More...

#include <errno.h>
#include <ipxe/weierstrass.h>

Go to the source code of this file.

Macros

#define WEIERSTRASS_zero   WEIERSTRASS_a
 Zero register (for add/subtract operations.
#define WEIERSTRASS_REGISTER(name)
 Construct big integer register index.
#define WEIERSTRASS_OP(opcode, dest, left, right)
 Define a bytecode operation.
#define WEIERSTRASS_OPCODE(op)
 Extract bytecode operation code.
#define WEIERSTRASS_DEST(op)
 Extract destination big integer register.
#define WEIERSTRASS_LEFT(op)
 Extract left source big integer register.
#define WEIERSTRASS_RIGHT(op)
 Extract right source big integer register.
#define WEIERSTRASS_ADD3(dest, augend, addend)
 Define a three-argument addition operation.
#define WEIERSTRASS_ADD2(augend, addend)
 Define a two-argument addition operation.
#define WEIERSTRASS_MOV(dest, source)
 Define a move operation.
#define WEIERSTRASS_SUB3(dest, minuend, subtrahend, multiple)
 Define a three-argument subtraction operation.
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)
 Define a two-argument subtraction operation.
#define WEIERSTRASS_STOP   WEIERSTRASS_SUB2 ( zero, zero, 0N )
 Define a stop operation.
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)
 Define a three-argument multiplication operation.
#define WEIERSTRASS_MUL2(multiplicand, multiplier)
 Define a two-argument multiplication operation.
#define weierstrass_add(curve, augend, addend, result)
 Add points on curve.
#define weierstrass_verify(curve, point)
 Verify freshly initialised point is on curve.
#define weierstrass_init(curve, point, temp, data)
 Initialise curve point.
#define weierstrass_done(curve, point, temp, out)
 Finalise curve point.

Enumerations

enum  weierstrass_register {
  WEIERSTRASS_a = 0 , WEIERSTRASS_3b , WEIERSTRASS_x1 , WEIERSTRASS_y1 ,
  WEIERSTRASS_z1 , WEIERSTRASS_x2 , WEIERSTRASS_y2 , WEIERSTRASS_z2 ,
  WEIERSTRASS_Wt , WEIERSTRASS_Wxy , WEIERSTRASS_Wyz , WEIERSTRASS_Wzx ,
  WEIERSTRASS_Wp , WEIERSTRASS_x3 , WEIERSTRASS_y3 , WEIERSTRASS_z3 ,
  WEIERSTRASS_NUM_REGISTERS = 16
}
 Big integer register names. More...
enum  weierstrass_opcode {
  WEIERSTRASS_OP_SUB_0N = 0 , WEIERSTRASS_OP_SUB_2N = WEIERSTRASS_2N , WEIERSTRASS_OP_SUB_4N = WEIERSTRASS_4N , WEIERSTRASS_OP_ADD ,
  WEIERSTRASS_OP_MUL
}
 Bytecode operation codes. More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static void weierstrass_init_curve (struct weierstrass_curve *curve)
 Initialise curve.
static void weierstrass_exec (const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
 Execute bytecode instruction.
static void weierstrass_add_raw (const struct weierstrass_curve *curve, const bigint_element_t *augend0, const bigint_element_t *addend0, bigint_element_t *result0)
 Add points on curve.
static void weierstrass_add_ladder (const bigint_element_t *operand0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp __unused)
 Add points on curve as part of a Montgomery ladder.
static int weierstrass_verify_raw (const struct weierstrass_curve *curve, const bigint_element_t *point0)
 Verify freshly initialised point is on curve.
static int weierstrass_init_raw (struct weierstrass_curve *curve, bigint_element_t *point0, bigint_element_t *temp0, const void *data)
 Initialise curve point.
static void weierstrass_done_raw (struct weierstrass_curve *curve, bigint_element_t *point0, bigint_element_t *temp0, void *out)
 Finalise curve point.
int weierstrass_is_infinity (struct weierstrass_curve *curve, const void *point)
 Check if this is the point at infinity.
int weierstrass_multiply (struct weierstrass_curve *curve, const void *base, const void *scalar, void *result)
 Multiply curve point by scalar.
int weierstrass_add_once (struct weierstrass_curve *curve, const void *addend, const void *augend, void *result)
 Add curve points (as a one-off operation)

Detailed Description

Weierstrass elliptic curves.

The implementation is based upon Algorithm 1 from "Complete addition formulas for prime order elliptic curves" (Joost Renes, Craig Costello, and Lejla Batina), available from

https://www.microsoft.com/en-us/research/wp-content/uploads/2016/06/complete-2.pdf

The steps within the algorithm have been reordered and temporary variables shuffled to reduce stack usage, and calculations are carried out modulo small multiples of the field prime in order to elide reductions after intermediate addition and subtraction operations.

The algorithm is encoded using a bytecode representation, since this substantially reduces the code size compared to direct implementation of the big integer operations.

Definition in file weierstrass.c.

Macro Definition Documentation

◆ WEIERSTRASS_zero

#define WEIERSTRASS_zero   WEIERSTRASS_a

Zero register (for add/subtract operations.

Definition at line 92 of file weierstrass.c.

◆ WEIERSTRASS_REGISTER

#define WEIERSTRASS_REGISTER ( name)
Value:
_C2 ( WEIERSTRASS_, name )
const char * name
Definition ath9k_hw.c:1986
#define _C2(x, y)
Concatenate expanded arguments.
Definition compiler.h:48

Construct big integer register index.

Definition at line 95 of file weierstrass.c.

◆ WEIERSTRASS_OP

#define WEIERSTRASS_OP ( opcode,
dest,
left,
right )
Value:
( ( (opcode) << 12 ) | \
( WEIERSTRASS_REGISTER ( dest ) << 8 ) | \
( WEIERSTRASS_REGISTER ( left ) << 4 ) | \
( WEIERSTRASS_REGISTER ( right ) << 0 ) )
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
uint8_t opcode
Opcode.
Definition ena.h:5
#define WEIERSTRASS_REGISTER(name)
Construct big integer register index.
Definition weierstrass.c:95

Define a bytecode operation.

Parameters
opcodeOperation code
destDestination big integer register name
leftLeft source big integer register name
rightRight source big integer register name

Definition at line 119 of file weierstrass.c.

119#define WEIERSTRASS_OP( opcode, dest, left, right ) \
120 ( ( (opcode) << 12 ) | \
121 ( WEIERSTRASS_REGISTER ( dest ) << 8 ) | \
122 ( WEIERSTRASS_REGISTER ( left ) << 4 ) | \
123 ( WEIERSTRASS_REGISTER ( right ) << 0 ) )

◆ WEIERSTRASS_OPCODE

#define WEIERSTRASS_OPCODE ( op)
Value:
( ( (op) >> 12 ) & 0xf )
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327

Extract bytecode operation code.

Definition at line 126 of file weierstrass.c.

Referenced by weierstrass_exec().

◆ WEIERSTRASS_DEST

#define WEIERSTRASS_DEST ( op)
Value:
( ( (op) >> 8 ) & 0xf )

Extract destination big integer register.

Definition at line 129 of file weierstrass.c.

Referenced by weierstrass_exec().

◆ WEIERSTRASS_LEFT

#define WEIERSTRASS_LEFT ( op)
Value:
( ( (op) >> 4 ) & 0xf )

Extract left source big integer register.

Definition at line 132 of file weierstrass.c.

Referenced by weierstrass_exec().

◆ WEIERSTRASS_RIGHT

#define WEIERSTRASS_RIGHT ( op)
Value:
( ( (op) >> 0 ) & 0xf )

Extract right source big integer register.

Definition at line 135 of file weierstrass.c.

Referenced by weierstrass_exec().

◆ WEIERSTRASS_ADD3

#define WEIERSTRASS_ADD3 ( dest,
augend,
addend )
Value:
WEIERSTRASS_OP ( WEIERSTRASS_OP_ADD, dest, augend, addend )
#define WEIERSTRASS_OP(opcode, dest, left, right)
Define a bytecode operation.
@ WEIERSTRASS_OP_ADD
Add big integers.

Define a three-argument addition operation.

Definition at line 138 of file weierstrass.c.

138#define WEIERSTRASS_ADD3( dest, augend, addend ) \
139 WEIERSTRASS_OP ( WEIERSTRASS_OP_ADD, dest, augend, addend )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_ADD2

#define WEIERSTRASS_ADD2 ( augend,
addend )
Value:
WEIERSTRASS_ADD3 ( augend, augend, addend )
#define WEIERSTRASS_ADD3(dest, augend, addend)
Define a three-argument addition operation.

Define a two-argument addition operation.

Definition at line 142 of file weierstrass.c.

142#define WEIERSTRASS_ADD2( augend, addend ) \
143 WEIERSTRASS_ADD3 ( augend, augend, addend )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_MOV

#define WEIERSTRASS_MOV ( dest,
source )
Value:
WEIERSTRASS_ADD3( dest, source, zero )

Define a move operation.

Definition at line 146 of file weierstrass.c.

146#define WEIERSTRASS_MOV( dest, source ) \
147 WEIERSTRASS_ADD3( dest, source, zero )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_SUB3

#define WEIERSTRASS_SUB3 ( dest,
minuend,
subtrahend,
multiple )
Value:
WEIERSTRASS_OP ( _C2 ( WEIERSTRASS_OP_SUB_, multiple ), \
dest, minuend, subtrahend )

Define a three-argument subtraction operation.

Definition at line 150 of file weierstrass.c.

150#define WEIERSTRASS_SUB3( dest, minuend, subtrahend, multiple ) \
151 WEIERSTRASS_OP ( _C2 ( WEIERSTRASS_OP_SUB_, multiple ), \
152 dest, minuend, subtrahend )

◆ WEIERSTRASS_SUB2

#define WEIERSTRASS_SUB2 ( minuend,
subtrahend,
multiple )
Value:
WEIERSTRASS_SUB3 ( minuend, minuend, subtrahend, multiple )
#define WEIERSTRASS_SUB3(dest, minuend, subtrahend, multiple)
Define a three-argument subtraction operation.

Define a two-argument subtraction operation.

Definition at line 155 of file weierstrass.c.

155#define WEIERSTRASS_SUB2( minuend, subtrahend, multiple ) \
156 WEIERSTRASS_SUB3 ( minuend, minuend, subtrahend, multiple )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_STOP

#define WEIERSTRASS_STOP   WEIERSTRASS_SUB2 ( zero, zero, 0N )

Define a stop operation.

Definition at line 159 of file weierstrass.c.

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_MUL3

#define WEIERSTRASS_MUL3 ( dest,
multiplicand,
multiplier )
Value:
static const uint32_t multiplier
Port multiplier number.
Definition bigint.h:335
@ WEIERSTRASS_OP_MUL
Multiply big integers (and perform Montgomery reduction)

Define a three-argument multiplication operation.

Definition at line 162 of file weierstrass.c.

162#define WEIERSTRASS_MUL3( dest, multiplicand, multiplier ) \
163 WEIERSTRASS_OP ( WEIERSTRASS_OP_MUL, dest, multiplicand, multiplier )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ WEIERSTRASS_MUL2

#define WEIERSTRASS_MUL2 ( multiplicand,
multiplier )
Value:
WEIERSTRASS_MUL3 ( multiplicand, multiplicand, multiplier )
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)
Define a three-argument multiplication operation.

Define a two-argument multiplication operation.

Definition at line 166 of file weierstrass.c.

166#define WEIERSTRASS_MUL2( multiplicand, multiplier ) \
167 WEIERSTRASS_MUL3 ( multiplicand, multiplicand, multiplier )

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ weierstrass_add

#define weierstrass_add ( curve,
augend,
addend,
result )
Value:
do { \
weierstrass_add_raw ( (curve), (augend)->all.element, \
(addend)->all.element, \
(result)->all.element ); \
} while ( 0 )
uint16_t result
Definition hyperv.h:33

Add points on curve.

Parameters
curveWeierstrass curve
augendPoint (x1,y1,z1) to be added
addendPoint (x2,y2,z2) to be added
result0Point (x3,y3,z3) to hold result

Definition at line 630 of file weierstrass.c.

630#define weierstrass_add( curve, augend, addend, result ) do { \
631 weierstrass_add_raw ( (curve), (augend)->all.element, \
632 (addend)->all.element, \
633 (result)->all.element ); \
634 } while ( 0 )

Referenced by weierstrass_add_ladder(), and weierstrass_add_once().

◆ weierstrass_verify

#define weierstrass_verify ( curve,
point )
Value:
( { \
weierstrass_verify_raw ( (curve), (point)->all.element ); \
} )

Verify freshly initialised point is on curve.

Parameters
curveWeierstrass curve
pointPoint (x,y,z) to be verified
Return values
rcReturn status code

Definition at line 767 of file weierstrass.c.

767#define weierstrass_verify( curve, point ) ( { \
768 weierstrass_verify_raw ( (curve), (point)->all.element ); \
769 } )

Referenced by weierstrass_init_raw().

◆ weierstrass_init

#define weierstrass_init ( curve,
point,
temp,
data )
Value:
( { \
weierstrass_init_raw ( (curve), (point)->all.element, \
(temp)->all.element, (data) ); \
} )
uint8_t data[48]
Additional event data.
Definition ena.h:11

Initialise curve point.

Parameters
curveWeierstrass curve
pointPoint (x,y,z) to be filled in
tempTemporary point buffer
dataRaw curve point
Return values
rcReturn status code

Definition at line 845 of file weierstrass.c.

845#define weierstrass_init( curve, point, temp, data ) ( { \
846 weierstrass_init_raw ( (curve), (point)->all.element, \
847 (temp)->all.element, (data) ); \
848 } )

Referenced by weierstrass_add_once(), and weierstrass_multiply().

◆ weierstrass_done

#define weierstrass_done ( curve,
point,
temp,
out )
Value:
( { \
weierstrass_done_raw ( (curve), (point)->all.element, \
(temp)->all.element, (out) ); \
} )
__be32 out[4]
Definition CIB_PRM.h:8

Finalise curve point.

Parameters
curveWeierstrass curve
pointPoint (x,y,z)
tempTemporary point buffer
outOutput buffer
Return values
rcReturn status code

Definition at line 908 of file weierstrass.c.

908#define weierstrass_done( curve, point, temp, out ) ( { \
909 weierstrass_done_raw ( (curve), (point)->all.element, \
910 (temp)->all.element, (out) ); \
911 } )

Referenced by weierstrass_add_once(), and weierstrass_multiply().

Enumeration Type Documentation

◆ weierstrass_register

Big integer register names.

Enumerator
WEIERSTRASS_a 
WEIERSTRASS_3b 
WEIERSTRASS_x1 
WEIERSTRASS_y1 
WEIERSTRASS_z1 
WEIERSTRASS_x2 
WEIERSTRASS_y2 
WEIERSTRASS_z2 
WEIERSTRASS_Wt 
WEIERSTRASS_Wxy 
WEIERSTRASS_Wyz 
WEIERSTRASS_Wzx 
WEIERSTRASS_Wp 
WEIERSTRASS_x3 
WEIERSTRASS_y3 
WEIERSTRASS_z3 
WEIERSTRASS_NUM_REGISTERS 

Definition at line 52 of file weierstrass.c.

52 {
53
54 /*
55 * Read-only registers
56 */
57
58 /* Curve constant "a" (for multiply), zero (for add/subtract) */
59 WEIERSTRASS_a = 0,
60 /* Curve constant "3b" */
62 /* Augend (x,y,z) co-ordinates */
66 /* Addend (x,y,z) co-ordinates */
70
71 /*
72 * Read-write registers
73 */
74
75 /* Temporary working registers */
80 /* Low half of multiplication product */
82 /* Result (x,y,z) co-ordinates */
86
87 /* Number of registers */
89};
@ WEIERSTRASS_Wt
Definition weierstrass.c:76
@ WEIERSTRASS_x3
Definition weierstrass.c:83
@ WEIERSTRASS_NUM_REGISTERS
Definition weierstrass.c:88
@ WEIERSTRASS_a
Definition weierstrass.c:59
@ WEIERSTRASS_y2
Definition weierstrass.c:68
@ WEIERSTRASS_3b
Definition weierstrass.c:61
@ WEIERSTRASS_Wp
Definition weierstrass.c:81
@ WEIERSTRASS_Wxy
Definition weierstrass.c:77
@ WEIERSTRASS_y3
Definition weierstrass.c:84
@ WEIERSTRASS_Wyz
Definition weierstrass.c:78
@ WEIERSTRASS_y1
Definition weierstrass.c:64
@ WEIERSTRASS_x2
Definition weierstrass.c:67
@ WEIERSTRASS_z3
Definition weierstrass.c:85
@ WEIERSTRASS_x1
Definition weierstrass.c:63
@ WEIERSTRASS_z2
Definition weierstrass.c:69
@ WEIERSTRASS_Wzx
Definition weierstrass.c:79
@ WEIERSTRASS_z1
Definition weierstrass.c:65

◆ weierstrass_opcode

Bytecode operation codes.

Enumerator
WEIERSTRASS_OP_SUB_0N 

Subtract big integers (and add nothing)

WEIERSTRASS_OP_SUB_2N 

Subtract big integers (and add 2N)

WEIERSTRASS_OP_SUB_4N 

Subtract big integers (and add 4N)

WEIERSTRASS_OP_ADD 

Add big integers.

WEIERSTRASS_OP_MUL 

Multiply big integers (and perform Montgomery reduction)

Definition at line 98 of file weierstrass.c.

98 {
99 /** Subtract big integers (and add nothing)*/
101 /** Subtract big integers (and add 2N) */
103 /** Subtract big integers (and add 4N) */
105 /** Add big integers */
107 /** Multiply big integers (and perform Montgomery reduction) */
109};
@ WEIERSTRASS_OP_SUB_2N
Subtract big integers (and add 2N)
@ WEIERSTRASS_OP_SUB_4N
Subtract big integers (and add 4N)
@ WEIERSTRASS_OP_SUB_0N
Subtract big integers (and add nothing)
@ WEIERSTRASS_2N
Definition weierstrass.h:73
@ WEIERSTRASS_4N
Definition weierstrass.h:74

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ weierstrass_init_curve()

void weierstrass_init_curve ( struct weierstrass_curve * curve)
static

Initialise curve.

Parameters
curveWeierstrass curve

Definition at line 174 of file weierstrass.c.

174 {
175 unsigned int size = curve->size;
176 bigint_t ( size ) __attribute__ (( may_alias )) *prime =
177 ( ( void * ) curve->prime[0] );
178 bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
179 ( ( void * ) curve->fermat );
180 bigint_t ( size ) __attribute__ (( may_alias )) *square =
181 ( ( void * ) curve->square );
182 bigint_t ( size ) __attribute__ (( may_alias )) *one =
183 ( ( void * ) curve->one );
184 bigint_t ( size ) __attribute__ (( may_alias )) *a =
185 ( ( void * ) curve->a );
186 bigint_t ( size ) __attribute__ (( may_alias )) *b3 =
187 ( ( void * ) curve->b3 );
188 bigint_t ( size ) __attribute__ (( may_alias )) *mont =
189 ( ( void * ) curve->mont[0] );
190 bigint_t ( size ) __attribute__ (( may_alias )) *temp =
191 ( ( void * ) curve->prime[1] );
192 bigint_t ( size * 2 ) __attribute__ (( may_alias )) *product =
193 ( ( void * ) temp );
194 bigint_t ( size ) __attribute__ (( may_alias )) *two =
195 ( ( void * ) temp );
196 static const uint8_t one_raw[] = { 1 };
197 static const uint8_t two_raw[] = { 2 };
198 size_t len = curve->len;
199 unsigned int i;
200
201 /* Initialise field prime */
202 bigint_init ( prime, curve->prime_raw, len );
203 DBGC ( curve, "WEIERSTRASS %s N = %s\n",
204 curve->name, bigint_ntoa ( prime ) );
205
206 /* Calculate Montgomery constant R^2 mod N */
207 bigint_reduce ( prime, square );
208 DBGC ( curve, "WEIERSTRASS %s R^2 = %s mod N\n",
209 curve->name, bigint_ntoa ( square ) );
210
211 /* Calculate constant "3b" */
212 bigint_init ( b3, curve->b_raw, len );
213 DBGC ( curve, "WEIERSTRASS %s b = %s\n",
214 curve->name, bigint_ntoa ( b3 ) );
215 bigint_copy ( b3, a );
216 bigint_add ( b3, b3 );
217 bigint_add ( a, b3 );
218
219 /* Initialise "a" */
220 bigint_init ( a, curve->a_raw, len );
221 DBGC ( curve, "WEIERSTRASS %s a = %s\n",
222 curve->name, bigint_ntoa ( a ) );
223
224 /* Initialise "1" */
225 bigint_init ( one, one_raw, sizeof ( one_raw ) );
226
227 /* Convert relevant constants to Montgomery form
228 *
229 * We rely on the fact that the prime multiples have not yet
230 * been calculated, and so can be used as a temporary buffer.
231 */
232 for ( i = 0 ; i < WEIERSTRASS_NUM_MONT ; i++ ) {
233 static const char *names[] = { " ", " a", "3b" };
234 bigint_multiply ( &mont[i], square, product );
235 bigint_montgomery ( prime, product, &mont[i] );
236 DBGC ( curve, "WEIERSTRASS %s %sR = %s mod N\n",
237 curve->name, names[i], bigint_ntoa ( &mont[i] ) );
238 }
239
240 /* Calculate constant "N-2"
241 *
242 * We rely on the fact that the prime multiples have not yet
243 * been calculated, and so can be used as a temporary buffer.
244 */
245 bigint_copy ( prime, fermat );
246 bigint_init ( two, two_raw, sizeof ( two_raw ) );
247 bigint_subtract ( two, fermat );
248 DBGC ( curve, "WEIERSTRASS %s N-2 = %s\n",
249 curve->name, bigint_ntoa ( fermat ) );
250
251 /* Calculate multiples of field prime */
252 for ( i = 1 ; i < WEIERSTRASS_NUM_MULTIPLES ; i++ ) {
253 bigint_copy ( &prime[ i - 1 ], &prime[i] );
254 bigint_add ( &prime[i], &prime[i] );
255 DBGC ( curve, "WEIERSTRASS %s %dN = %s\n",
256 curve->name, ( 1 << i ), bigint_ntoa ( &prime[i] ) );
257 }
258}
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:505
uint16_t size
Buffer size.
Definition dwmac.h:3
#define __attribute__(x)
Definition compiler.h:10
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition bigint.h:274
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition bigint.h:99
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition bigint.h:314
#define bigint_copy(source, dest)
Copy big integer.
Definition bigint.h:235
#define bigint_t(size)
Define a big-integer type.
Definition bigint.h:20
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition bigint.h:260
#define bigint_add(addend, value)
Add big integers.
Definition bigint.h:87
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition bigint.h:50
#define bigint_init(value, data, len)
Initialise big integer.
Definition bigint.h:62
uint8_t product
Product string.
Definition smbios.h:5
bigint_element_t * mont[WEIERSTRASS_NUM_MONT]
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
size_t len
Length of raw scalar values.
Definition weierstrass.h:98
const uint8_t * a_raw
Constant "a".
bigint_element_t * one
Cached constant "1", in Montgomery form.
bigint_element_t * square
Cached Montgomery constant (R^2 mod N)
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
const unsigned int size
Number of elements in scalar values.
Definition weierstrass.h:94
const char * name
Curve name.
Definition weierstrass.h:96
const uint8_t * b_raw
Constant "b".
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
bigint_element_t * a
Cached constant "a", in Montgomery form.
const uint8_t * prime_raw
Field prime.
#define WEIERSTRASS_NUM_MONT
Number of cached in Montgomery form for each Weierstrass curve.
Definition weierstrass.h:79
@ WEIERSTRASS_NUM_MULTIPLES
Definition weierstrass.h:75

References __attribute__, weierstrass_curve::a, weierstrass_curve::a_raw, weierstrass_curve::b3, weierstrass_curve::b_raw, bigint_add, bigint_copy, bigint_init, bigint_montgomery, bigint_multiply, bigint_ntoa, bigint_reduce, bigint_subtract, bigint_t, DBGC, weierstrass_curve::fermat, len, weierstrass_curve::len, weierstrass_curve::mont, weierstrass_curve::name, weierstrass_curve::one, weierstrass_curve::prime, weierstrass_curve::prime_raw, product, size, weierstrass_curve::size, weierstrass_curve::square, WEIERSTRASS_NUM_MONT, and WEIERSTRASS_NUM_MULTIPLES.

Referenced by weierstrass_init_raw().

◆ weierstrass_exec()

void weierstrass_exec ( const struct weierstrass_curve * curve,
void ** regs,
unsigned int size,
unsigned int op )
static

Execute bytecode instruction.

Parameters
curveWeierstrass curve
regsRegisters
sizeBig integer size
opOperation

Definition at line 268 of file weierstrass.c.

270 {
271 const bigint_t ( size ) __attribute__ (( may_alias ))
272 *prime = ( ( const void * ) curve->prime[0] );
273 bigint_t ( size * 2 ) __attribute__ (( may_alias ))
275 bigint_t ( size ) __attribute__ (( may_alias )) *dest;
276 const bigint_t ( size ) __attribute__ (( may_alias )) *left;
277 const bigint_t ( size ) __attribute__ (( may_alias )) *right;
278 const bigint_t ( size ) __attribute__ (( may_alias )) *addend;
279 const bigint_t ( size ) __attribute__ (( may_alias )) *subtrahend;
280 unsigned int op_code;
281 unsigned int op_dest;
282 unsigned int op_left;
283 unsigned int op_right;
284
285 /* Decode instruction */
286 op_code = WEIERSTRASS_OPCODE ( op );
287 op_dest = WEIERSTRASS_DEST ( op );
288 op_left = WEIERSTRASS_LEFT ( op );
289 op_right = WEIERSTRASS_RIGHT ( op );
290 dest = regs[op_dest];
291 left = regs[op_left];
292 right = regs[op_right];
293
294 /* Check destination is a writable register */
295 assert ( op_dest >= WEIERSTRASS_Wt );
296
297 /* Handle multiplications */
298 if ( op_code == WEIERSTRASS_OP_MUL ) {
299 assert ( op_left != WEIERSTRASS_Wp );
300 assert ( op_right != WEIERSTRASS_Wp );
301 bigint_multiply ( left, right, product );
303 DBGCP ( curve, "WEIERSTRASS %s R%d := R%d x R%d = %s\n",
304 curve->name, op_dest, op_left, op_right,
305 bigint_ntoa ( dest ) );
306 return;
307 }
308
309 /* Copy left source, if required */
310 if ( op_dest != op_left )
311 bigint_copy ( left, dest );
312
313 /* Do nothing more if addend/subtrahend is zero */
314 if ( ! op_right ) {
315 DBGCP ( curve, "WEIERSTRASS %s R%d := R%d = %s\n",
316 curve->name, op_dest, op_left, bigint_ntoa ( dest ) );
317 return;
318 }
319
320 /* Determine addend and subtrahend */
321 addend = NULL;
322 subtrahend = NULL;
323 if ( op_code == WEIERSTRASS_OP_ADD ) {
324 DBGCP ( curve, "WEIERSTRASS %s R%d := R%d + R%d = ",
325 curve->name, op_dest, op_left, op_right );
326 addend = ( ( const void * ) right );
327 } else {
328 subtrahend = ( ( const void * ) right );
329 if ( op_code > WEIERSTRASS_OP_SUB_0N ) {
330 DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d + "
331 "%dN = ", curve->name, op_dest, op_left,
332 op_right, ( 1 << op_code ) );
333 addend = ( ( const void * ) curve->prime[op_code] );
334 } else {
335 DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d = ",
336 curve->name, op_dest, op_left, op_right );
337 }
338 }
339
340 /* Perform addition and subtraction */
341 if ( addend )
342 bigint_add ( addend, dest );
343 if ( subtrahend )
344 bigint_subtract ( subtrahend, dest );
345 DBGCP ( curve, "%s\n", bigint_ntoa ( dest ) );
346}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
#define DBGCP(...)
Definition compiler.h:539
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition bigint.h:300
struct i386_regs regs
Definition registers.h:1
#define WEIERSTRASS_DEST(op)
Extract destination big integer register.
#define WEIERSTRASS_RIGHT(op)
Extract right source big integer register.
#define WEIERSTRASS_LEFT(op)
Extract left source big integer register.
#define WEIERSTRASS_OPCODE(op)
Extract bytecode operation code.

References __attribute__, assert, bigint_add, bigint_copy, bigint_montgomery_relaxed, bigint_multiply, bigint_ntoa, bigint_subtract, bigint_t, DBGCP, dest, weierstrass_curve::name, NULL, op, weierstrass_curve::prime, product, regs, size, WEIERSTRASS_DEST, WEIERSTRASS_LEFT, WEIERSTRASS_OP_ADD, WEIERSTRASS_OP_MUL, WEIERSTRASS_OP_SUB_0N, WEIERSTRASS_OPCODE, WEIERSTRASS_RIGHT, WEIERSTRASS_Wp, and WEIERSTRASS_Wt.

Referenced by weierstrass_add_raw(), and weierstrass_verify_raw().

◆ weierstrass_add_raw()

void weierstrass_add_raw ( const struct weierstrass_curve * curve,
const bigint_element_t * augend0,
const bigint_element_t * addend0,
bigint_element_t * result0 )
static

Add points on curve.

Parameters
curveWeierstrass curve
augend0Element 0 of point (x1,y1,z1) to be added
addend0Element 0 of point (x2,y2,z2) to be added
result0Element 0 of point (x3,y3,z3) to hold result

Points are represented in projective coordinates, with all values in Montgomery form and in the range [0,4N) where N is the field prime.

The augend may have the same value as the addend (i.e. this routine may be used to perform point doubling as well as point addition), and either or both may be the point at infinity.

The result may overlap either input, since the inputs are fully consumed before the result is written.

Definition at line 367 of file weierstrass.c.

370 {
371 unsigned int size = curve->size;
372 const bigint_t ( size ) __attribute__ (( may_alias ))
373 *prime = ( ( const void * ) curve->prime[0] );
374 const bigint_t ( size ) __attribute__ (( may_alias ))
375 *a = ( ( const void * ) curve->a );
376 const bigint_t ( size ) __attribute__ (( may_alias ))
377 *b3 = ( ( const void * ) curve->b3 );
378 const weierstrass_t ( size ) __attribute__ (( may_alias ))
379 *augend = ( ( const void * ) augend0 );
380 const weierstrass_t ( size ) __attribute__ (( may_alias ))
381 *addend = ( ( const void * ) addend0 );
382 weierstrass_t ( size ) __attribute__ (( may_alias ))
383 *result = ( ( void * ) result0 );
384 struct {
385 bigint_t ( size ) Wt;
386 bigint_t ( size ) Wxy;
387 bigint_t ( size ) Wyz;
388 bigint_t ( size ) Wzx;
389 bigint_t ( size * 2 ) Wp;
390 } temp;
392 unsigned int schedule;
393 const uint16_t *op;
394 unsigned int i;
395
396 /* On entry, we assume that x1, x2, y1, y2, z1, z2 are all in
397 * the range [0,4N). Additions will extend the range.
398 * Subtractions will extend the range (and require an addition
399 * of a suitable multiple of the modulus to ensure that the
400 * result is a positive value). Relaxed Montgomery
401 * multiplications will reduce the range to [0,2N). The
402 * outputs x3, y3, z3 will be in the range [0,4N) and
403 * therefore usable as subsequent inputs.
404 */
405 static const uint16_t ops[] = {
406 /* [Wxy] Qxy = (x1+y1)*(x2+y2) (mod 2N) */
407 WEIERSTRASS_ADD3 ( Wt, x1, y1 ),
408 WEIERSTRASS_ADD3 ( Wxy, x2, y2 ),
409 WEIERSTRASS_MUL2 ( Wxy, Wt ),
410 /* [Wyz] Qyz = (y1+z1)*(y2+z2) (mod 2N) */
411 WEIERSTRASS_ADD3 ( Wt, y1, z1 ),
412 WEIERSTRASS_ADD3 ( Wyz, y2, z2 ),
413 WEIERSTRASS_MUL2 ( Wyz, Wt ),
414 /* [Wzx] Qzx = (z1+x1)*(z2+x2) (mod 2N) */
415 WEIERSTRASS_ADD3 ( Wt, z1, x1 ),
416 WEIERSTRASS_ADD3 ( Wzx, z2, x2 ),
417 WEIERSTRASS_MUL2 ( Wzx, Wt ),
418 /* [x3] Px = x1*x2 (mod 2N) */
419 WEIERSTRASS_MUL3 ( x3, x1, x2 ),
420 /* [y3] Py = y1*y2 (mod 2N) */
421 WEIERSTRASS_MUL3 ( y3, y1, y2 ),
422 /* [z3] Pz = z1*z2 (mod 2N) */
423 WEIERSTRASS_MUL3 ( z3, z1, z2 ),
424 /* [Wxy] Rxy = Qxy - Px - Py (mod 6N)
425 * = (x1+y1)*(x2+y2) - x1*x2 - y1*y2 (mod 6N)
426 * = x1*y2 + x2*y1 (mod 6N)
427 */
428 WEIERSTRASS_SUB2 ( Wxy, x3, 0N ),
429 WEIERSTRASS_SUB2 ( Wxy, y3, 4N ),
430 /* [Wyz] Ryz = Qyz - Py - Pz (mod 6N)
431 * = (y1+z1)*(y2+z2) - y1*y2 - z1*z2 (mod 6N)
432 * = y1*z2 + y2*z1 (mod 6N)
433 */
434 WEIERSTRASS_SUB2 ( Wyz, y3, 0N ),
435 WEIERSTRASS_SUB2 ( Wyz, z3, 4N ),
436 /* [Wzx] Rzx = Qzx - Pz - Px (mod 6N)
437 * = (z1+x1)*(z2+x2) - z1*z2 - x1*x2 (mod 6N)
438 * = x1*z2 + x2*z1 (mod 6N)
439 */
440 WEIERSTRASS_SUB2 ( Wzx, z3, 0N ),
441 WEIERSTRASS_SUB2 ( Wzx, x3, 4N ),
442 /* [Wt] aRzx = a * Rzx (mod 2N)
443 * = a * (x1*z2 + x2*z1) (mod 2N)
444 */
445 WEIERSTRASS_MUL3 ( Wt, a, Wzx ),
446 /* [Wp] 3bPz = 3b * Pz (mod 2N)
447 * = 3b*z1*z2 (mod 2N)
448 */
449 WEIERSTRASS_MUL3 ( Wp, 3b, z3 ),
450 /* [Wp] Sy = aRzx + 3bPz (mod 4N)
451 * = a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 4N)
452 */
453 WEIERSTRASS_ADD2 ( Wp, Wt ),
454 /* [Wt] Syz = Py + Sy (mod 6N)
455 * = y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 6N)
456 */
457 WEIERSTRASS_ADD3 ( Wt, y3, Wp ),
458 /* [y3] Sxy = Py - Sy (mod 6N)
459 * = y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2 (mod 6N)
460 */
461 WEIERSTRASS_SUB2 ( y3, Wp, 4N ),
462 /* [z3] aPz = a * Pz (mod 2N)
463 * = a * z1*z2 (mod 2N)
464 */
465 WEIERSTRASS_MUL2 ( z3, a ),
466 /* [Wzx] 3bRzx = 3b * Rzx (mod 2N)
467 * = 3b * (x1*z2 + x2*z1) (mod 2N)
468 */
469 WEIERSTRASS_MUL2 ( Wzx, 3b ),
470 /* [x3] aPzx' = Px - aPz (mod 4N)
471 * = x1*x2 - a*z1*z2 (mod 4N)
472 */
473 WEIERSTRASS_SUB2 ( x3, z3, 2N ),
474 /* [Wp] Szx = a * aPzx' (mod 2N)
475 * = a * (x1*x2 - a*z1*z2) (mod 2N)
476 * = a*x1*x2 - (a^2)*z1*z2 (mod 2N)
477 */
478 WEIERSTRASS_MUL3 ( Wp, a, x3 ),
479 /* [x3] Px = aPzx' + aPz (mod 6N)
480 * = x1*x2 - a*z1*z2 + a*z1*z2 (mod 6N)
481 * = x1*x2 (mod 6N)
482 */
483 WEIERSTRASS_ADD2 ( x3, z3 ),
484 /* [Wzx] Tzx = 3bRzx + Szx (mod 4N)
485 * = a*x1*x2 + 3b*(x1*z2 + x2*z1) -
486 * (a^2)*z1*z2 (mod 4N)
487 */
488 WEIERSTRASS_ADD2 ( Wzx, Wp ),
489 /* [z3] aPzx = Px + aPz (mod 8N)
490 * = x1*x2 + a*z1*z2 (mod 8N)
491 */
492 WEIERSTRASS_ADD2 ( z3, x3 ),
493 /* [x3] 2Px = Px + Px (mod 12N)
494 * = 2*x1*x2 (mod 12N)
495 */
496 WEIERSTRASS_ADD2 ( x3, x3 ),
497 /* [x3] Tyz = 2Px + aPzx (mod 20N)
498 * = 2*x1*x2 + x1*x2 + a*z1*z2 (mod 20N)
499 * = 3*x1*x2 + a*z1*z2 (mod 20N)
500 */
501 WEIERSTRASS_ADD2 ( x3, z3 ),
502 /* [z3] Syz = Syz (mod 6N)
503 * = y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2 (mod 6N)
504 */
505 WEIERSTRASS_MOV ( z3, Wt ),
506 /* [Wt] Tyz = Tyz (mod 20N)
507 * = 3*x1*x2 + a*z1*z2 (mod 20N)
508 */
509 WEIERSTRASS_MOV ( Wt, x3 ),
510 /* [x3] Ux = Rxy * Sxy (mod 2N)
511 * = (x1*y2 + x2*y1) *
512 * (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2) (mod 2N)
513 */
514 WEIERSTRASS_MUL3 ( x3, Wxy, y3 ),
515 /* [y3] Uy = Syz * Sxy (mod 2N)
516 * = (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) *
517 * (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2) (mod 2N)
518 */
519 WEIERSTRASS_MUL2 ( y3, z3 ),
520 /* [z3] Uz = Ryz * Syz (mod 2N)
521 * = (y1*z2 + y2*z1) *
522 * (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) (mod 2N)
523 */
524 WEIERSTRASS_MUL2 ( z3, Wyz ),
525 /* [Wp] Vx = Ryz * Tzx (mod 2N)
526 * = (y1*z2 + y2*z1) *
527 * (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)
528 * (mod 2N)
529 */
530 WEIERSTRASS_MUL3 ( Wp, Wyz, Wzx ),
531 /* [x3] x3 = Ux - Vx (mod 4N)
532 * = ((x1*y2 + x2*y1) *
533 * (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2)) -
534 * ((y1*z2 + y2*z1) *
535 * (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2))
536 * (mod 4N)
537 */
538 WEIERSTRASS_SUB2 ( x3, Wp, 2N ),
539 /* [Wp] Vy = Tyz * Tzx (mod 2N)
540 * = (3*x1*x2 + a*z1*z2) *
541 * (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)
542 * (mod 2N)
543 */
544 WEIERSTRASS_MUL3 ( Wp, Wt, Wzx ),
545 /* [y3] y3 = Vy + Uy (mod 4N)
546 * = ((3*x1*x2 + a*z1*z2) *
547 * (a*x1*x2 + 3b*(x1*z2 + x2*z1) - (a^2)*z1*z2)) +
548 * ((y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2) *
549 * (y1*y2 - a*(x1*z2 + x2*z1) - 3b*z1*z2))
550 * (mod 4N)
551 */
552 WEIERSTRASS_ADD2 ( y3, Wp ),
553 /* [Wp] Vz = Rxy * Tyz (mod 2N)
554 * = (x1*y2 + x2*y1) * (3*x1*x2 + a*z1*z2) (mod 2N)
555 */
556 WEIERSTRASS_MUL3 ( Wp, Wxy, Wt ),
557 /* [z3] z3 = Uz + Vz (mod 4N)
558 * = ((y1*z2 + y2*z1) *
559 * (y1*y2 + a*(x1*z2 + x2*z1) + 3b*z1*z2)) +
560 * ((x1*y2 + x2*y1) * (3*x1*x2 + a*z1*z2))
561 * (mod 4N)
562 */
563 WEIERSTRASS_ADD2 ( z3, Wp ),
564 /* Stop */
566 };
567
568 /* Initialise register list */
569 regs[WEIERSTRASS_a] = ( ( void * ) a );
570 regs[WEIERSTRASS_3b] = ( ( void * ) b3 );
571 regs[WEIERSTRASS_x1] = ( ( void * ) &augend->x );
572 regs[WEIERSTRASS_x2] = ( ( void * ) &addend->x );
573 regs[WEIERSTRASS_x3] = ( ( void * ) &result->x );
574 regs[WEIERSTRASS_Wt] = &temp;
575 schedule = ( ( ( 1 << WEIERSTRASS_NUM_REGISTERS ) - 1 )
576 - ( 1 << WEIERSTRASS_a )
577 - ( 1 << WEIERSTRASS_3b )
578 - ( 1 << WEIERSTRASS_x1 )
579 - ( 1 << WEIERSTRASS_x2 )
580 - ( 1 << WEIERSTRASS_x3 )
581 - ( 1 << WEIERSTRASS_Wt ) );
582 for ( i = 0 ; schedule ; i++, schedule >>= 1 ) {
583 if ( schedule & 1 )
584 regs[i] = ( regs[ i - 1 ] + sizeof ( *prime ) );
585 }
586 DBGC2 ( curve, "WEIERSTRASS %s augend (%s,",
587 curve->name, bigint_ntoa ( &augend->x ) );
588 DBGC2 ( curve, "%s,", bigint_ntoa ( &augend->y ) );
589 DBGC2 ( curve, "%s)\n", bigint_ntoa ( &augend->z ) );
590 DBGC2 ( curve, "WEIERSTRASS %s addend (%s,",
591 curve->name, bigint_ntoa ( &addend->x ) );
592 DBGC2 ( curve, "%s,", bigint_ntoa ( &addend->y ) );
593 DBGC2 ( curve, "%s)\n", bigint_ntoa ( &addend->z ) );
594
595 /* Sanity checks */
596 assert ( regs[WEIERSTRASS_a] == a );
597 assert ( regs[WEIERSTRASS_3b] == b3 );
598 assert ( regs[WEIERSTRASS_x1] == &augend->x );
599 assert ( regs[WEIERSTRASS_y1] == &augend->y );
600 assert ( regs[WEIERSTRASS_z1] == &augend->z );
601 assert ( regs[WEIERSTRASS_x2] == &addend->x );
602 assert ( regs[WEIERSTRASS_y2] == &addend->y );
603 assert ( regs[WEIERSTRASS_z2] == &addend->z );
604 assert ( regs[WEIERSTRASS_x3] == &result->x );
605 assert ( regs[WEIERSTRASS_y3] == &result->y );
606 assert ( regs[WEIERSTRASS_z3] == &result->z );
607 assert ( regs[WEIERSTRASS_Wt] == &temp.Wt );
608 assert ( regs[WEIERSTRASS_Wxy] == &temp.Wxy );
609 assert ( regs[WEIERSTRASS_Wyz] == &temp.Wyz );
610 assert ( regs[WEIERSTRASS_Wzx] == &temp.Wzx );
611 assert ( regs[WEIERSTRASS_Wp] == &temp.Wp );
612
613 /* Execute bytecode instruction sequence */
614 for ( op = ops ; *op != WEIERSTRASS_STOP ; op++ )
615 weierstrass_exec ( curve, regs, size, *op );
616 DBGC2 ( curve, "WEIERSTRASS %s result (%s,",
617 curve->name, bigint_ntoa ( &result->x ) );
618 DBGC2 ( curve, "%s,", bigint_ntoa ( &result->y ) );
619 DBGC2 ( curve, "%s)\n", bigint_ntoa ( &result->z ) );
620}
unsigned short uint16_t
Definition stdint.h:11
#define DBGC2(...)
Definition compiler.h:522
#define WEIERSTRASS_STOP
Define a stop operation.
#define WEIERSTRASS_MUL2(multiplicand, multiplier)
Define a two-argument multiplication operation.
#define WEIERSTRASS_MOV(dest, source)
Define a move operation.
static void weierstrass_exec(const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
Execute bytecode instruction.
#define WEIERSTRASS_ADD2(augend, addend)
Define a two-argument addition operation.
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)
Define a two-argument subtraction operation.
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition weierstrass.h:58

References __attribute__, weierstrass_curve::a, assert, weierstrass_curve::b3, bigint_ntoa, bigint_t, DBGC2, weierstrass_curve::name, op, weierstrass_curve::prime, regs, result, size, weierstrass_curve::size, WEIERSTRASS_3b, WEIERSTRASS_a, WEIERSTRASS_ADD2, WEIERSTRASS_ADD3, weierstrass_exec(), WEIERSTRASS_MOV, WEIERSTRASS_MUL2, WEIERSTRASS_MUL3, WEIERSTRASS_NUM_REGISTERS, WEIERSTRASS_STOP, WEIERSTRASS_SUB2, weierstrass_t, WEIERSTRASS_Wp, WEIERSTRASS_Wt, WEIERSTRASS_Wxy, WEIERSTRASS_Wyz, WEIERSTRASS_Wzx, WEIERSTRASS_x1, WEIERSTRASS_x2, WEIERSTRASS_x3, WEIERSTRASS_y1, WEIERSTRASS_y2, WEIERSTRASS_y3, WEIERSTRASS_z1, WEIERSTRASS_z2, and WEIERSTRASS_z3.

◆ weierstrass_add_ladder()

void weierstrass_add_ladder ( const bigint_element_t * operand0,
bigint_element_t * result0,
unsigned int size,
const void * ctx,
void *tmp __unused )
static

Add points on curve as part of a Montgomery ladder.

Parameters
operandElement 0 of first input operand (may overlap result)
resultElement 0 of second input operand and result
sizeNumber of elements in operands and result
ctxOperation context
tmpTemporary working space (not used)

Definition at line 645 of file weierstrass.c.

648 {
649 const struct weierstrass_curve *curve = ctx;
650 const weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
651 *operand = ( ( const void * ) operand0 );
652 weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
653 *result = ( ( void * ) result0 );
654
655 /* Add curve points */
656 assert ( size == bigint_size ( &operand->all ) );
657 assert ( size == bigint_size ( &result->all ) );
658 weierstrass_add ( curve, operand, result, result );
659}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
#define bigint_size(bigint)
Determine number of elements in big-integer type.
Definition bigint.h:41
A Weierstrass elliptic curve.
Definition weierstrass.h:92
#define weierstrass_add(curve, augend, addend, result)
Add points on curve.

References __attribute__, __unused, assert, bigint_size, ctx, result, size, weierstrass_curve::size, tmp, weierstrass_add, and weierstrass_t.

Referenced by weierstrass_multiply().

◆ weierstrass_verify_raw()

int weierstrass_verify_raw ( const struct weierstrass_curve * curve,
const bigint_element_t * point0 )
static

Verify freshly initialised point is on curve.

Parameters
curveWeierstrass curve
point0Element 0 of point (x,y,z) to be verified
Return values
rcReturn status code

As with point addition, points are represented in projective coordinates, with all values in Montgomery form and in the range [0,4N) where N is the field prime.

This verification logic is valid only for points that have been freshly constructed via weierstrass_init() (i.e. must either have z=1 or be the point at infinity (0,1,0)).

Definition at line 676 of file weierstrass.c.

677 {
678 unsigned int size = curve->size;
679 const bigint_t ( size ) __attribute__ (( may_alias ))
680 *prime = ( ( const void * ) curve->prime[0] );
681 const bigint_t ( size ) __attribute__ (( may_alias ))
682 *a = ( ( const void * ) curve->a );
683 const bigint_t ( size ) __attribute__ (( may_alias ))
684 *b3 = ( ( const void * ) curve->b3 );
685 const weierstrass_t ( size ) __attribute__ (( may_alias ))
686 *point = ( ( const void * ) point0 );
687 struct {
688 bigint_t ( size ) Wt;
689 bigint_t ( size * 2 ) Wp;
690 } temp;
692 const uint16_t *op;
693
694 /* Calculate 3*(x^3 + a*x + b - y^2) */
695 static const uint16_t ops[] = {
696 /* [Wt] Tx = x^2 (mod 2N) */
697 WEIERSTRASS_MUL3 ( Wt, x1, x1 ),
698 /* [Wt] Txa = Tx + a (mod 3N)
699 * = x^2 + a (mod 3N)
700 */
701 WEIERSTRASS_MOV ( Wp, a ),
702 WEIERSTRASS_ADD2 ( Wt, Wp ),
703 /* [Wt] Txax = Txa * x (mod 2N)
704 * = (x^2 + a)*x (mod 2N)
705 * = x^3 + a*x (mod 2N)
706 */
707 WEIERSTRASS_MUL2 ( Wt, x1 ),
708 /* [Wp] Ty = y^2 (mod 2N) */
709 WEIERSTRASS_MUL3 ( Wp, y1, y1 ),
710 /* [Wt] Txaxy = Txax - Ty (mod 4N)
711 * = x^3 + a*x - y^2 (mod 4N)
712 */
713 WEIERSTRASS_SUB2 ( Wt, Wp, 2N ),
714 /* [Wp] 2Txaxy = Txaxy + Txaxy (mod 8N)
715 * = 2*(x^3 + a*x - y^2) (mod 8N)
716 */
717 WEIERSTRASS_ADD3 ( Wp, Wt, Wt ),
718 /* [Wt] 3Txaxy = 2Txaxy + Txaxy (mod 12N)
719 * = 3*(x^3 + a*x - y^2) (mod 12N)
720 */
721 WEIERSTRASS_ADD2 ( Wt, Wp ),
722 /* [Wt] 3Txaxyb = 3Txaxy + 3b (mod 13N)
723 * = 3*(x^3 + a*x - y^2) + 3b (mod 13N)
724 * = 3*(x^3 + a*x + b - y^2) (mod 13N)
725 */
726 WEIERSTRASS_ADD2 ( Wt, 3b ),
727 /* [Wt] check = 3Txaxyb * z (mod 2N)
728 * = 3*(x^3 + a*x + b - y^2) * z (mod 2N)
729 */
730 WEIERSTRASS_MUL2 ( Wt, z1 ),
731 /* Stop */
733 };
734
735 /* Initialise register list */
736 regs[WEIERSTRASS_a] = ( ( void * ) a );
737 regs[WEIERSTRASS_3b] = ( ( void * ) b3 );
738 regs[WEIERSTRASS_x1] = ( ( void * ) &point->x );
739 regs[WEIERSTRASS_y1] = ( ( void * ) &point->y );
740 regs[WEIERSTRASS_z1] = ( ( void * ) &point->z );
741 regs[WEIERSTRASS_Wt] = &temp.Wt;
742 regs[WEIERSTRASS_Wp] = &temp.Wp;
743
744 /* Execute bytecode instruction sequence */
745 for ( op = ops ; *op != WEIERSTRASS_STOP ; op++ )
746 weierstrass_exec ( curve, regs, size, *op );
747
748 /* Check that result is zero (modulo the field prime) */
749 bigint_grow ( &temp.Wt, &temp.Wp );
750 bigint_montgomery ( prime, &temp.Wp, &temp.Wt );
751 if ( ! bigint_is_zero ( &temp.Wt ) ) {
752 DBGC ( curve, "WEIERSTRASS %s base point is not on curve\n",
753 curve->name );
754 return -EINVAL;
755 }
756
757 return 0;
758}
#define EINVAL
Invalid argument.
Definition errno.h:429
#define bigint_grow(source, dest)
Grow big integer.
Definition bigint.h:209
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition bigint.h:134

References __attribute__, weierstrass_curve::a, weierstrass_curve::b3, bigint_grow, bigint_is_zero, bigint_montgomery, bigint_t, DBGC, EINVAL, weierstrass_curve::name, op, weierstrass_curve::prime, regs, size, weierstrass_curve::size, WEIERSTRASS_3b, WEIERSTRASS_a, WEIERSTRASS_ADD2, WEIERSTRASS_ADD3, weierstrass_exec(), WEIERSTRASS_MOV, WEIERSTRASS_MUL2, WEIERSTRASS_MUL3, WEIERSTRASS_NUM_REGISTERS, WEIERSTRASS_STOP, WEIERSTRASS_SUB2, weierstrass_t, WEIERSTRASS_Wp, WEIERSTRASS_Wt, WEIERSTRASS_x1, WEIERSTRASS_y1, and WEIERSTRASS_z1.

◆ weierstrass_init_raw()

int weierstrass_init_raw ( struct weierstrass_curve * curve,
bigint_element_t * point0,
bigint_element_t * temp0,
const void * data )
static

Initialise curve point.

Parameters
curveWeierstrass curve
point0Element 0 of point (x,y,z) to be filled in
temp0Element 0 of temporary point buffer
dataRaw curve point
Return values
rcReturn status code

Definition at line 780 of file weierstrass.c.

782 {
783 unsigned int size = curve->size;
784 size_t len = curve->len;
785 const bigint_t ( size ) __attribute__ (( may_alias )) *prime =
786 ( ( const void * ) curve->prime[0] );
787 const bigint_t ( size ) __attribute__ (( may_alias )) *prime2 =
788 ( ( const void * ) curve->prime[WEIERSTRASS_2N] );
789 const bigint_t ( size ) __attribute__ (( may_alias )) *square =
790 ( ( const void * ) curve->square );
791 const bigint_t ( size ) __attribute__ (( may_alias )) *one =
792 ( ( const void * ) curve->one );
793 weierstrass_t ( size ) __attribute__ (( may_alias ))
794 *point = ( ( void * ) point0 );
795 union {
796 bigint_t ( size * 2 ) product;
797 weierstrass_t ( size ) point;
798 } __attribute__ (( may_alias )) *temp = ( ( void * ) temp0 );
799 size_t offset;
800 int is_infinite;
801 unsigned int i;
802 int rc;
803
804 /* Initialise curve, if not already done
805 *
806 * The least significant element of the field prime must be
807 * odd, and so the least significant element of the
808 * (initialised) first multiple of the field prime must be
809 * non-zero.
810 */
811 if ( ! prime2->element[0] )
812 weierstrass_init_curve ( curve );
813
814 /* Convert input to projective coordinates in Montgomery form */
815 DBGC ( curve, "WEIERSTRASS %s point (", curve->name );
816 for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
817 bigint_init ( &point->axis[i], ( data + offset ), len );
818 DBGC ( curve, "%s%s", ( i ? "," : "" ),
819 bigint_ntoa ( &point->axis[i] ) );
820 bigint_multiply ( &point->axis[i], square, &temp->product );
821 bigint_montgomery_relaxed ( prime, &temp->product,
822 &point->axis[i] );
823 }
824 memset ( &point->z, 0, sizeof ( point->z ) );
825 is_infinite = bigint_is_zero ( &point->xy );
826 bigint_copy ( one, &point->axis[ is_infinite ? 1 : 2 ] );
827 DBGC ( curve, ")\n" );
828
829 /* Verify point is on curve */
830 if ( ( rc = weierstrass_verify ( curve, point ) ) != 0 )
831 return rc;
832
833 return 0;
834}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
uint16_t offset
Offset to command line.
Definition bzimage.h:3
void * memset(void *dest, int character, size_t len) __nonnull
#define weierstrass_verify(curve, point)
Verify freshly initialised point is on curve.
static void weierstrass_init_curve(struct weierstrass_curve *curve)
Initialise curve.
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition weierstrass.h:17

References __attribute__, bigint_copy, bigint_init, bigint_is_zero, bigint_montgomery_relaxed, bigint_multiply, bigint_ntoa, bigint_t, data, DBGC, len, weierstrass_curve::len, memset(), weierstrass_curve::name, offset, weierstrass_curve::one, weierstrass_curve::prime, product, rc, size, weierstrass_curve::size, weierstrass_curve::square, WEIERSTRASS_2N, WEIERSTRASS_AXES, weierstrass_init_curve(), weierstrass_t, and weierstrass_verify.

◆ weierstrass_done_raw()

void weierstrass_done_raw ( struct weierstrass_curve * curve,
bigint_element_t * point0,
bigint_element_t * temp0,
void * out )
static

Finalise curve point.

Parameters
curveWeierstrass curve
point0Element 0 of point (x,y,z)
temp0Element 0 of temporary point buffer
outOutput buffer

Definition at line 858 of file weierstrass.c.

860 {
861 unsigned int size = curve->size;
862 size_t len = curve->len;
863 const bigint_t ( size ) __attribute__ (( may_alias )) *prime =
864 ( ( const void * ) curve->prime[0] );
865 const bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
866 ( ( const void * ) curve->fermat );
867 const bigint_t ( size ) __attribute__ (( may_alias )) *one =
868 ( ( const void * ) curve->one );
869 weierstrass_t ( size ) __attribute__ (( may_alias ))
870 *point = ( ( void * ) point0 );
871 union {
872 bigint_t ( size * 2 ) product;
873 weierstrass_t ( size ) point;
874 } __attribute__ (( may_alias )) *temp = ( ( void * ) temp0 );
875 size_t offset;
876 unsigned int i;
877
878 /* Invert result Z co-ordinate (via Fermat's little theorem) */
879 bigint_copy ( one, &temp->point.z );
880 bigint_ladder ( &temp->point.z, &point->z, fermat,
881 bigint_mod_exp_ladder, prime, &temp->product );
882
883 /* Convert result back to affine co-ordinates */
884 DBGC ( curve, "WEIERSTRASS %s result (", curve->name );
885 for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
886 bigint_multiply ( &point->axis[i], &temp->point.z,
887 &temp->product );
888 bigint_montgomery_relaxed ( prime, &temp->product,
889 &point->axis[i] );
890 bigint_grow ( &point->axis[i], &temp->product );
891 bigint_montgomery ( prime, &temp->product, &point->axis[i] );
892 DBGC ( curve, "%s%s", ( i ? "," : "" ),
893 bigint_ntoa ( &point->axis[i] ) );
894 bigint_done ( &point->axis[i], ( out + offset ), len );
895 }
896 DBGC ( curve, ")\n" );
897}
void bigint_mod_exp_ladder(const bigint_element_t *multiplier0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp)
Perform modular multiplication as part of a Montgomery ladder.
Definition bigint.c:720
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition bigint.h:330
#define bigint_done(value, out, len)
Finalise big integer.
Definition bigint.h:75

References __attribute__, bigint_copy, bigint_done, bigint_grow, bigint_ladder, bigint_mod_exp_ladder(), bigint_montgomery, bigint_montgomery_relaxed, bigint_multiply, bigint_ntoa, bigint_t, DBGC, weierstrass_curve::fermat, len, weierstrass_curve::len, weierstrass_curve::name, offset, weierstrass_curve::one, out, weierstrass_curve::prime, product, size, weierstrass_curve::size, WEIERSTRASS_AXES, and weierstrass_t.

◆ weierstrass_is_infinity()

int weierstrass_is_infinity ( struct weierstrass_curve * curve,
const void * point )

Check if this is the point at infinity.

Parameters
pointCurve point
Return values
is_infinityThis is the point at infinity

Definition at line 919 of file weierstrass.c.

920 {
921 unsigned int size = curve->size;
922 size_t len = curve->len;
923 struct {
924 bigint_t ( size ) axis;
925 } temp;
926 size_t offset;
927 int is_finite = 0;
928 unsigned int i;
929
930 /* We use all zeroes to represent the point at infinity */
931 DBGC ( curve, "WEIERSTRASS %s point (", curve->name );
932 for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
933 bigint_init ( &temp.axis, ( point + offset ), len );
934 DBGC ( curve, "%s%s", ( i ? "," : "" ),
935 bigint_ntoa ( &temp.axis ) );
936 is_finite |= ( ! bigint_is_zero ( &temp.axis ) );
937 }
938 DBGC ( curve, ") is%s infinity\n", ( is_finite ? " not" : "" ) );
939
940 return ( ! is_finite );
941}

References bigint_init, bigint_is_zero, bigint_ntoa, bigint_t, DBGC, len, weierstrass_curve::len, weierstrass_curve::name, offset, size, weierstrass_curve::size, and WEIERSTRASS_AXES.

◆ weierstrass_multiply()

int weierstrass_multiply ( struct weierstrass_curve * curve,
const void * base,
const void * scalar,
void * result )

Multiply curve point by scalar.

Parameters
curveWeierstrass curve
baseBase point
scalarScalar multiple
resultResult point to fill in
Return values
rcReturn status code

Definition at line 952 of file weierstrass.c.

953 {
954 unsigned int size = curve->size;
955 size_t len = curve->len;
956 const bigint_t ( size ) __attribute__ (( may_alias )) *one =
957 ( ( const void * ) curve->one );
958 struct {
960 weierstrass_t ( size ) multiple;
961 bigint_t ( bigint_required_size ( len ) ) scalar;
962 } temp;
963 int rc;
964
965 /* Convert input to projective coordinates in Montgomery form */
966 if ( ( rc = weierstrass_init ( curve, &temp.multiple, &temp.result,
967 base ) ) != 0 ) {
968 return rc;
969 }
970
971 /* Construct identity element (the point at infinity) */
972 memset ( &temp.result, 0, sizeof ( temp.result ) );
973 bigint_copy ( one, &temp.result.y );
974
975 /* Initialise scalar */
976 bigint_init ( &temp.scalar, scalar, len );
977 DBGC ( curve, "WEIERSTRASS %s scalar %s\n",
978 curve->name, bigint_ntoa ( &temp.scalar ) );
979
980 /* Perform multiplication via Montgomery ladder */
981 bigint_ladder ( &temp.result.all, &temp.multiple.all, &temp.scalar,
983
984 /* Convert result back to affine co-ordinates */
985 weierstrass_done ( curve, &temp.result, &temp.multiple, result );
986
987 return 0;
988}
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition bigint.h:31
uint32_t base
Base.
Definition librm.h:3
#define weierstrass_done(curve, point, temp, out)
Finalise curve point.
static void weierstrass_add_ladder(const bigint_element_t *operand0, bigint_element_t *result0, unsigned int size, const void *ctx, void *tmp __unused)
Add points on curve as part of a Montgomery ladder.
#define weierstrass_init(curve, point, temp, data)
Initialise curve point.

References __attribute__, base, bigint_copy, bigint_init, bigint_ladder, bigint_ntoa, bigint_required_size, bigint_t, DBGC, len, weierstrass_curve::len, memset(), weierstrass_curve::name, NULL, weierstrass_curve::one, rc, result, size, weierstrass_curve::size, weierstrass_add_ladder(), weierstrass_done, weierstrass_init, and weierstrass_t.

◆ weierstrass_add_once()

int weierstrass_add_once ( struct weierstrass_curve * curve,
const void * addend,
const void * augend,
void * result )

Add curve points (as a one-off operation)

Parameters
curveWeierstrass curve
addendCurve point to add
augendCurve point to add
resultCurve point to hold result
Return values
rcReturn status code

Definition at line 999 of file weierstrass.c.

1001 {
1002 unsigned int size = curve->size;
1003 struct {
1004 weierstrass_t ( size ) addend;
1005 weierstrass_t ( size ) augend;
1007 } temp;
1008 int rc;
1009
1010 /* Convert inputs to projective coordinates in Montgomery form */
1011 if ( ( rc = weierstrass_init ( curve, &temp.addend, &temp.result,
1012 addend ) ) != 0 ) {
1013 return rc;
1014 }
1015 if ( ( rc = weierstrass_init ( curve, &temp.augend, &temp.result,
1016 augend ) ) != 0 ) {
1017 return rc;
1018 }
1019
1020 /* Add curve points */
1021 weierstrass_add ( curve, &temp.augend, &temp.addend, &temp.result );
1022
1023 /* Convert result back to affine co-ordinates */
1024 weierstrass_done ( curve, &temp.result, &temp.addend, result );
1025
1026 return 0;
1027}

References rc, result, size, weierstrass_curve::size, weierstrass_add, weierstrass_done, weierstrass_init, and weierstrass_t.