iPXE
Macros | Enumerations | Functions
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. More...
 
#define WEIERSTRASS_REGISTER(name)   _C2 ( WEIERSTRASS_, name )
 Construct big integer register index. More...
 
#define WEIERSTRASS_OP(opcode, dest, left, right)
 Define a bytecode operation. More...
 
#define WEIERSTRASS_OPCODE(op)   ( ( (op) >> 12 ) & 0xf )
 Extract bytecode operation code. More...
 
#define WEIERSTRASS_DEST(op)   ( ( (op) >> 8 ) & 0xf )
 Extract destination big integer register. More...
 
#define WEIERSTRASS_LEFT(op)   ( ( (op) >> 4 ) & 0xf )
 Extract left source big integer register. More...
 
#define WEIERSTRASS_RIGHT(op)   ( ( (op) >> 0 ) & 0xf )
 Extract right source big integer register. More...
 
#define WEIERSTRASS_ADD3(dest, augend, addend)   WEIERSTRASS_OP ( WEIERSTRASS_OP_ADD, dest, augend, addend )
 Define a three-argument addition operation. More...
 
#define WEIERSTRASS_ADD2(augend, addend)   WEIERSTRASS_ADD3 ( augend, augend, addend )
 Define a two-argument addition operation. More...
 
#define WEIERSTRASS_MOV(dest, source)   WEIERSTRASS_ADD3( dest, source, zero )
 Define a move operation. More...
 
#define WEIERSTRASS_SUB3(dest, minuend, subtrahend, multiple)
 Define a three-argument subtraction operation. More...
 
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)   WEIERSTRASS_SUB3 ( minuend, minuend, subtrahend, multiple )
 Define a two-argument subtraction operation. More...
 
#define WEIERSTRASS_STOP   WEIERSTRASS_SUB2 ( zero, zero, 0N )
 Define a stop operation. More...
 
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)   WEIERSTRASS_OP ( WEIERSTRASS_OP_MUL, dest, multiplicand, multiplier )
 Define a three-argument multiplication operation. More...
 
#define WEIERSTRASS_MUL2(multiplicand, multiplier)   WEIERSTRASS_MUL3 ( multiplicand, multiplicand, multiplier )
 Define a two-argument multiplication operation. More...
 
#define weierstrass_add(curve, augend, addend, result)
 Add points on curve. More...
 
#define weierstrass_verify(curve, point)
 Verify freshly initialised point is on curve. More...
 
#define weierstrass_init(curve, point, temp, data)
 Initialise curve point. More...
 
#define weierstrass_done(curve, point, temp, out)
 Finalise curve point. More...
 

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. More...
 
static void weierstrass_exec (const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
 Execute bytecode instruction. More...
 
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. More...
 
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. More...
 
static int weierstrass_verify_raw (const struct weierstrass_curve *curve, const bigint_element_t *point0)
 Verify freshly initialised point is on curve. More...
 
static int weierstrass_init_raw (struct weierstrass_curve *curve, bigint_element_t *point0, bigint_element_t *temp0, const void *data)
 Initialise curve point. More...
 
static void weierstrass_done_raw (struct weierstrass_curve *curve, bigint_element_t *point0, bigint_element_t *temp0, void *out)
 Finalise curve point. More...
 
int weierstrass_is_infinity (struct weierstrass_curve *curve, const void *point)
 Check if this is the point at infinity. More...
 
int weierstrass_multiply (struct weierstrass_curve *curve, const void *base, const void *scalar, void *result)
 Multiply curve point by scalar. More...
 
int weierstrass_add_once (struct weierstrass_curve *curve, const void *addend, const void *augend, void *result)
 Add curve points (as a one-off operation) More...
 

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)    _C2 ( WEIERSTRASS_, name )

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 ) )
uint8_t opcode
Opcode.
Definition: ena.h:16
#define WEIERSTRASS_REGISTER(name)
Construct big integer register index.
Definition: weierstrass.c:95
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" return dest
Definition: string.h:151

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.

◆ WEIERSTRASS_OPCODE

#define WEIERSTRASS_OPCODE (   op)    ( ( (op) >> 12 ) & 0xf )

Extract bytecode operation code.

Definition at line 126 of file weierstrass.c.

◆ WEIERSTRASS_DEST

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

Extract destination big integer register.

Definition at line 129 of file weierstrass.c.

◆ WEIERSTRASS_LEFT

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

Extract left source big integer register.

Definition at line 132 of file weierstrass.c.

◆ WEIERSTRASS_RIGHT

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

Extract right source big integer register.

Definition at line 135 of file weierstrass.c.

◆ WEIERSTRASS_ADD3

#define WEIERSTRASS_ADD3 (   dest,
  augend,
  addend 
)    WEIERSTRASS_OP ( WEIERSTRASS_OP_ADD, dest, augend, addend )

Define a three-argument addition operation.

Definition at line 138 of file weierstrass.c.

◆ WEIERSTRASS_ADD2

#define WEIERSTRASS_ADD2 (   augend,
  addend 
)    WEIERSTRASS_ADD3 ( augend, augend, addend )

Define a two-argument addition operation.

Definition at line 142 of file weierstrass.c.

◆ WEIERSTRASS_MOV

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

Define a move operation.

Definition at line 146 of file weierstrass.c.

◆ WEIERSTRASS_SUB3

#define WEIERSTRASS_SUB3 (   dest,
  minuend,
  subtrahend,
  multiple 
)
Value:
WEIERSTRASS_OP ( _C2 ( WEIERSTRASS_OP_SUB_, multiple ), \
dest, minuend, subtrahend )
#define WEIERSTRASS_OP(opcode, dest, left, right)
Define a bytecode operation.
Definition: weierstrass.c:119
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" return dest
Definition: string.h:151
EFI_SYSTEM_TABLE * _C2(PLATFORM, _systab)
System table passed to entry point.

Define a three-argument subtraction operation.

Definition at line 150 of file weierstrass.c.

◆ WEIERSTRASS_SUB2

#define WEIERSTRASS_SUB2 (   minuend,
  subtrahend,
  multiple 
)    WEIERSTRASS_SUB3 ( minuend, minuend, subtrahend, multiple )

Define a two-argument subtraction operation.

Definition at line 155 of file weierstrass.c.

◆ WEIERSTRASS_STOP

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

Define a stop operation.

Definition at line 159 of file weierstrass.c.

◆ WEIERSTRASS_MUL3

#define WEIERSTRASS_MUL3 (   dest,
  multiplicand,
  multiplier 
)    WEIERSTRASS_OP ( WEIERSTRASS_OP_MUL, dest, multiplicand, multiplier )

Define a three-argument multiplication operation.

Definition at line 162 of file weierstrass.c.

◆ WEIERSTRASS_MUL2

#define WEIERSTRASS_MUL2 (   multiplicand,
  multiplier 
)    WEIERSTRASS_MUL3 ( multiplicand, multiplicand, multiplier )

Define a two-argument multiplication operation.

Definition at line 166 of file weierstrass.c.

◆ 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.

◆ 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.

◆ 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:22

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.

◆ 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:36

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.

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_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 };
Add big integers.
Definition: weierstrass.c:106
Subtract big integers (and add 2N)
Definition: weierstrass.c:102
Subtract big integers (and add nothing)
Definition: weierstrass.c:100
Multiply big integers (and perform Montgomery reduction)
Definition: weierstrass.c:108
Subtract big integers (and add 4N)
Definition: weierstrass.c:104

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED  )

◆ weierstrass_init_curve()

static 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 }
#define __attribute__(x)
Definition: compiler.h:10
bigint_element_t * square
Cached Montgomery constant (R^2 mod N)
Definition: weierstrass.h:113
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
uint16_t size
Buffer size.
Definition: dwmac.h:14
bigint_element_t * mont[WEIERSTRASS_NUM_MONT]
Definition: weierstrass.h:124
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
Definition: weierstrass.h:122
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
ring len
Length.
Definition: dwmac.h:231
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
Definition: weierstrass.h:111
const uint8_t * b_raw
Constant "b".
Definition: weierstrass.h:104
bigint_element_t * a
Cached constant "a", in Montgomery form.
Definition: weierstrass.h:120
#define WEIERSTRASS_NUM_MONT
Number of cached in Montgomery form for each Weierstrass curve.
Definition: weierstrass.h:79
const char * name
Curve name.
Definition: weierstrass.h:96
unsigned char uint8_t
Definition: stdint.h:10
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:118
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
#define bigint_reduce(modulus, result)
Reduce big integer R^2 modulo N.
Definition: bigint.h:274
uint8_t product
Product string.
Definition: smbios.h:17
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
#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
const uint8_t * prime_raw
Field prime.
Definition: weierstrass.h:100
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
const uint8_t * a_raw
Constant "a".
Definition: weierstrass.h:102

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, weierstrass_curve::len, 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()

static 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 __attribute__(x)
Definition: compiler.h:10
#define WEIERSTRASS_RIGHT(op)
Extract right source big integer register.
Definition: weierstrass.c:135
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_OPCODE(op)
Extract bytecode operation code.
Definition: weierstrass.c:126
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:300
Add big integers.
Definition: weierstrass.c:106
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
const char * name
Curve name.
Definition: weierstrass.h:96
struct i386_regs regs
Definition: registers.h:15
Subtract big integers (and add nothing)
Definition: weierstrass.c:100
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
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" return dest
Definition: string.h:151
#define DBGCP(...)
Definition: compiler.h:539
uint8_t product
Product string.
Definition: smbios.h:17
#define WEIERSTRASS_LEFT(op)
Extract left source big integer register.
Definition: weierstrass.c:132
#define WEIERSTRASS_DEST(op)
Extract destination big integer register.
Definition: weierstrass.c:129
Multiply big integers (and perform Montgomery reduction)
Definition: weierstrass.c:108
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:99
#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 NULL
NULL pointer (VOID *)
Definition: Base.h:322
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

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()

static 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 }
#define __attribute__(x)
Definition: compiler.h:10
unsigned short uint16_t
Definition: stdint.h:11
#define WEIERSTRASS_STOP
Define a stop operation.
Definition: weierstrass.c:159
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
static void weierstrass_exec(const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
Execute bytecode instruction.
Definition: weierstrass.c:268
uint16_t size
Buffer size.
Definition: dwmac.h:14
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
Definition: weierstrass.h:122
#define WEIERSTRASS_MOV(dest, source)
Define a move operation.
Definition: weierstrass.c:146
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)
Define a three-argument multiplication operation.
Definition: weierstrass.c:162
bigint_element_t * a
Cached constant "a", in Montgomery form.
Definition: weierstrass.h:120
const char * name
Curve name.
Definition: weierstrass.h:96
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)
Define a two-argument subtraction operation.
Definition: weierstrass.c:155
struct i386_regs regs
Definition: registers.h:15
uint16_t result
Definition: hyperv.h:33
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define DBGC2(...)
Definition: compiler.h:522
#define WEIERSTRASS_MUL2(multiplicand, multiplier)
Define a two-argument multiplication operation.
Definition: weierstrass.c:166
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
#define WEIERSTRASS_ADD3(dest, augend, addend)
Define a three-argument addition operation.
Definition: weierstrass.c:138
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
#define WEIERSTRASS_ADD2(augend, addend)
Define a two-argument addition operation.
Definition: weierstrass.c:142
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

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()

static 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 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define weierstrass_add(curve, augend, addend, result)
Add points on curve.
Definition: weierstrass.c:630
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
A 16-bit general register.
Definition: registers.h:24
uint16_t result
Definition: hyperv.h:33
#define bigint_size(bigint)
Determine number of elements in big-integer type.
Definition: bigint.h:41
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
A Weierstrass elliptic curve.
Definition: weierstrass.h:92

References __attribute__, assert(), bigint_size, ctx, result, size, weierstrass_curve::size, weierstrass_add, and weierstrass_t.

Referenced by weierstrass_multiply().

◆ weierstrass_verify_raw()

static 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 __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:429
unsigned short uint16_t
Definition: stdint.h:11
#define WEIERSTRASS_STOP
Define a stop operation.
Definition: weierstrass.c:159
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
static void weierstrass_exec(const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
Execute bytecode instruction.
Definition: weierstrass.c:268
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
#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
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
Definition: weierstrass.h:122
#define WEIERSTRASS_MOV(dest, source)
Define a move operation.
Definition: weierstrass.c:146
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)
Define a three-argument multiplication operation.
Definition: weierstrass.c:162
bigint_element_t * a
Cached constant "a", in Montgomery form.
Definition: weierstrass.h:120
const char * name
Curve name.
Definition: weierstrass.h:96
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)
Define a two-argument subtraction operation.
Definition: weierstrass.c:155
struct i386_regs regs
Definition: registers.h:15
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
#define WEIERSTRASS_MUL2(multiplicand, multiplier)
Define a two-argument multiplication operation.
Definition: weierstrass.c:166
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
#define WEIERSTRASS_ADD3(dest, augend, addend)
Define a three-argument addition operation.
Definition: weierstrass.c:138
#define WEIERSTRASS_ADD2(augend, addend)
Define a two-argument addition operation.
Definition: weierstrass.c:142
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

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()

static 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 }
#define __attribute__(x)
Definition: compiler.h:10
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
bigint_element_t * square
Cached Montgomery constant (R^2 mod N)
Definition: weierstrass.h:113
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:17
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
#define weierstrass_verify(curve, point)
Verify freshly initialised point is on curve.
Definition: weierstrass.c:767
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:134
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:300
static void weierstrass_init_curve(struct weierstrass_curve *curve)
Initialise curve.
Definition: weierstrass.c:174
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
ring len
Length.
Definition: dwmac.h:231
const char * name
Curve name.
Definition: weierstrass.h:96
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:118
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t product
Product string.
Definition: smbios.h:17
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, bigint_copy, bigint_init, bigint_is_zero, bigint_montgomery_relaxed, bigint_multiply, bigint_ntoa, bigint_t(), data, DBGC, weierstrass_curve::len, 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()

static 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 }
#define __attribute__(x)
Definition: compiler.h:10
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:109
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:17
#define DBGC(...)
Definition: compiler.h:505
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:209
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:300
__be32 out[4]
Definition: CIB_PRM.h:36
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
ring len
Length.
Definition: dwmac.h:231
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
Definition: weierstrass.h:111
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:75
const char * name
Curve name.
Definition: weierstrass.h:96
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:118
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:314
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:260
uint8_t product
Product string.
Definition: smbios.h:17
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:330
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
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

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, weierstrass_curve::len, 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 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:17
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:134
ring len
Length.
Definition: dwmac.h:231
const char * name
Curve name.
Definition: weierstrass.h:96
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.

References bigint_init, bigint_is_zero, bigint_ntoa, bigint_t(), DBGC, weierstrass_curve::len, 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,
982  weierstrass_add_ladder, curve, NULL );
983 
984  /* Convert result back to affine co-ordinates */
985  weierstrass_done ( curve, &temp.result, &temp.multiple, result );
986 
987  return 0;
988 }
#define weierstrass_init(curve, point, temp, data)
Initialise curve point.
Definition: weierstrass.c:845
#define __attribute__(x)
Definition: compiler.h:10
uint32_t base
Base.
Definition: librm.h:138
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:62
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.
Definition: weierstrass.c:645
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define weierstrass_done(curve, point, temp, out)
Finalise curve point.
Definition: weierstrass.c:908
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:235
ring len
Length.
Definition: dwmac.h:231
#define bigint_required_size(len)
Determine number of elements required for a big-integer type.
Definition: bigint.h:31
const char * name
Curve name.
Definition: weierstrass.h:96
size_t len
Length of raw scalar values.
Definition: weierstrass.h:98
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:118
uint16_t result
Definition: hyperv.h:33
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:330
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:50
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
typedef bigint_t(X25519_SIZE) x25519_t
An X25519 unsigned big integer used in internal calculations.
void * memset(void *dest, int character, size_t len) __nonnull

References __attribute__, base, bigint_copy, bigint_init, bigint_ladder, bigint_ntoa, bigint_required_size, bigint_t(), DBGC, weierstrass_curve::len, 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 }
#define weierstrass_init(curve, point, temp, data)
Initialise curve point.
Definition: weierstrass.c:845
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define weierstrass_add(curve, augend, addend, result)
Add points on curve.
Definition: weierstrass.c:630
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:58
#define weierstrass_done(curve, point, temp, out)
Finalise curve point.
Definition: weierstrass.c:908
uint16_t result
Definition: hyperv.h:33
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:94

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