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)
 
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 91 of file weierstrass.c.

◆ WEIERSTRASS_REGISTER

#define WEIERSTRASS_REGISTER (   name)    _C2 ( WEIERSTRASS_, name )

Construct big integer register index.

Definition at line 94 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:94
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:150

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 118 of file weierstrass.c.

◆ WEIERSTRASS_OPCODE

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

Extract bytecode operation code.

Definition at line 125 of file weierstrass.c.

◆ WEIERSTRASS_DEST

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

Extract destination big integer register.

Definition at line 128 of file weierstrass.c.

◆ WEIERSTRASS_LEFT

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

Extract left source big integer register.

Definition at line 131 of file weierstrass.c.

◆ WEIERSTRASS_RIGHT

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

Extract right source big integer register.

Definition at line 134 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 137 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 141 of file weierstrass.c.

◆ WEIERSTRASS_MOV

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

Define a move operation.

Definition at line 145 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:118
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:150
EFI_SYSTEM_TABLE * _C2(PLATFORM, _systab)
System table passed to entry point.

Define a three-argument subtraction operation.

Definition at line 149 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 154 of file weierstrass.c.

◆ WEIERSTRASS_STOP

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

Define a stop operation.

Definition at line 158 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 161 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 165 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 629 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 766 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 844 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 907 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 51 of file weierstrass.c.

51  {
52 
53  /*
54  * Read-only registers
55  */
56 
57  /* Curve constant "a" (for multiply), zero (for add/subtract) */
58  WEIERSTRASS_a = 0,
59  /* Curve constant "3b" */
61  /* Augend (x,y,z) co-ordinates */
65  /* Addend (x,y,z) co-ordinates */
69 
70  /*
71  * Read-write registers
72  */
73 
74  /* Temporary working registers */
79  /* Low half of multiplication product */
81  /* Result (x,y,z) co-ordinates */
85 
86  /* Number of registers */
88 };

◆ 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 97 of file weierstrass.c.

97  {
98  /** Subtract big integers (and add nothing)*/
100  /** Subtract big integers (and add 2N) */
102  /** Subtract big integers (and add 4N) */
104  /** Add big integers */
106  /** Multiply big integers (and perform Montgomery reduction) */
108 };
Add big integers.
Definition: weierstrass.c:105
Subtract big integers (and add 2N)
Definition: weierstrass.c:101
Subtract big integers (and add nothing)
Definition: weierstrass.c:99
Multiply big integers (and perform Montgomery reduction)
Definition: weierstrass.c:107
Subtract big integers (and add 4N)
Definition: weierstrass.c:103

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ weierstrass_init_curve()

static void weierstrass_init_curve ( struct weierstrass_curve curve)
static

Initialise curve.

Parameters
curveWeierstrass curve

Definition at line 173 of file weierstrass.c.

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

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 267 of file weierstrass.c.

269  {
270  const bigint_t ( size ) __attribute__ (( may_alias ))
271  *prime = ( ( const void * ) curve->prime[0] );
272  bigint_t ( size * 2 ) __attribute__ (( may_alias ))
274  bigint_t ( size ) __attribute__ (( may_alias )) *dest;
275  const bigint_t ( size ) __attribute__ (( may_alias )) *left;
276  const bigint_t ( size ) __attribute__ (( may_alias )) *right;
277  const bigint_t ( size ) __attribute__ (( may_alias )) *addend;
278  const bigint_t ( size ) __attribute__ (( may_alias )) *subtrahend;
279  unsigned int op_code;
280  unsigned int op_dest;
281  unsigned int op_left;
282  unsigned int op_right;
283 
284  /* Decode instruction */
285  op_code = WEIERSTRASS_OPCODE ( op );
286  op_dest = WEIERSTRASS_DEST ( op );
287  op_left = WEIERSTRASS_LEFT ( op );
288  op_right = WEIERSTRASS_RIGHT ( op );
289  dest = regs[op_dest];
290  left = regs[op_left];
291  right = regs[op_right];
292 
293  /* Check destination is a writable register */
294  assert ( op_dest >= WEIERSTRASS_Wt );
295 
296  /* Handle multiplications */
297  if ( op_code == WEIERSTRASS_OP_MUL ) {
298  assert ( op_left != WEIERSTRASS_Wp );
299  assert ( op_right != WEIERSTRASS_Wp );
300  bigint_multiply ( left, right, product );
302  DBGCP ( curve, "WEIERSTRASS %s R%d := R%d x R%d = %s\n",
303  curve->name, op_dest, op_left, op_right,
304  bigint_ntoa ( dest ) );
305  return;
306  }
307 
308  /* Copy left source, if required */
309  if ( op_dest != op_left )
310  bigint_copy ( left, dest );
311 
312  /* Do nothing more if addend/subtrahend is zero */
313  if ( ! op_right ) {
314  DBGCP ( curve, "WEIERSTRASS %s R%d := R%d = %s\n",
315  curve->name, op_dest, op_left, bigint_ntoa ( dest ) );
316  return;
317  }
318 
319  /* Determine addend and subtrahend */
320  addend = NULL;
321  subtrahend = NULL;
322  if ( op_code == WEIERSTRASS_OP_ADD ) {
323  DBGCP ( curve, "WEIERSTRASS %s R%d := R%d + R%d = ",
324  curve->name, op_dest, op_left, op_right );
325  addend = ( ( const void * ) right );
326  } else {
327  subtrahend = ( ( const void * ) right );
328  if ( op_code > WEIERSTRASS_OP_SUB_0N ) {
329  DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d + "
330  "%dN = ", curve->name, op_dest, op_left,
331  op_right, ( 1 << op_code ) );
332  addend = ( ( const void * ) curve->prime[op_code] );
333  } else {
334  DBGCP ( curve, "WEIERSTRASS %s R%d := R%d - R%d = ",
335  curve->name, op_dest, op_left, op_right );
336  }
337  }
338 
339  /* Perform addition and subtraction */
340  if ( addend )
341  bigint_add ( addend, dest );
342  if ( subtrahend )
343  bigint_subtract ( subtrahend, dest );
344  DBGCP ( curve, "%s\n", bigint_ntoa ( dest ) );
345 }
#define __attribute__(x)
Definition: compiler.h:10
#define WEIERSTRASS_RIGHT(op)
Extract right source big integer register.
Definition: weierstrass.c:134
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:108
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_OPCODE(op)
Extract bytecode operation code.
Definition: weierstrass.c:125
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:299
Add big integers.
Definition: weierstrass.c:105
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
const char * name
Curve name.
Definition: weierstrass.h:95
struct i386_regs regs
Definition: registers.h:15
Subtract big integers (and add nothing)
Definition: weierstrass.c:99
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:259
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:150
#define DBGCP(...)
Definition: compiler.h:539
uint8_t product
Product string.
Definition: smbios.h:16
#define WEIERSTRASS_LEFT(op)
Extract left source big integer register.
Definition: weierstrass.c:131
#define WEIERSTRASS_DEST(op)
Extract destination big integer register.
Definition: weierstrass.c:128
Multiply big integers (and perform Montgomery reduction)
Definition: weierstrass.c:107
#define bigint_subtract(subtrahend, value)
Subtract big integers.
Definition: bigint.h:98
#define bigint_add(addend, value)
Add big integers.
Definition: bigint.h:86
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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 366 of file weierstrass.c.

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

647  {
648  const struct weierstrass_curve *curve = ctx;
649  const weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
650  *operand = ( ( const void * ) operand0 );
651  weierstrass_t ( curve->size ) __attribute__ (( may_alias ))
652  *result = ( ( void * ) result0 );
653 
654  /* Add curve points */
655  assert ( size == bigint_size ( &operand->all ) );
656  assert ( size == bigint_size ( &result->all ) );
657  weierstrass_add ( curve, operand, result, result );
658 }
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:629
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
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:40
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
A Weierstrass elliptic curve.
Definition: weierstrass.h:91

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 675 of file weierstrass.c.

676  {
677  unsigned int size = curve->size;
678  const bigint_t ( size ) __attribute__ (( may_alias ))
679  *prime = ( ( const void * ) curve->prime[0] );
680  const bigint_t ( size ) __attribute__ (( may_alias ))
681  *a = ( ( const void * ) curve->a );
682  const bigint_t ( size ) __attribute__ (( may_alias ))
683  *b3 = ( ( const void * ) curve->b3 );
684  const weierstrass_t ( size ) __attribute__ (( may_alias ))
685  *point = ( ( const void * ) point0 );
686  struct {
687  bigint_t ( size ) Wt;
688  bigint_t ( size * 2 ) Wp;
689  } temp;
691  const uint16_t *op;
692 
693  /* Calculate 3*(x^3 + a*x + b - y^2) */
694  static const uint16_t ops[] = {
695  /* [Wt] Tx = x^2 (mod 2N) */
696  WEIERSTRASS_MUL3 ( Wt, x1, x1 ),
697  /* [Wt] Txa = Tx + a (mod 3N)
698  * = x^2 + a (mod 3N)
699  */
700  WEIERSTRASS_MOV ( Wp, a ),
701  WEIERSTRASS_ADD2 ( Wt, Wp ),
702  /* [Wt] Txax = Txa * x (mod 2N)
703  * = (x^2 + a)*x (mod 2N)
704  * = x^3 + a*x (mod 2N)
705  */
706  WEIERSTRASS_MUL2 ( Wt, x1 ),
707  /* [Wp] Ty = y^2 (mod 2N) */
708  WEIERSTRASS_MUL3 ( Wp, y1, y1 ),
709  /* [Wt] Txaxy = Txax - Ty (mod 4N)
710  * = x^3 + a*x - y^2 (mod 4N)
711  */
712  WEIERSTRASS_SUB2 ( Wt, Wp, 2N ),
713  /* [Wp] 2Txaxy = Txaxy + Txaxy (mod 8N)
714  * = 2*(x^3 + a*x - y^2) (mod 8N)
715  */
716  WEIERSTRASS_ADD3 ( Wp, Wt, Wt ),
717  /* [Wt] 3Txaxy = 2Txaxy + Txaxy (mod 12N)
718  * = 3*(x^3 + a*x - y^2) (mod 12N)
719  */
720  WEIERSTRASS_ADD2 ( Wt, Wp ),
721  /* [Wt] 3Txaxyb = 3Txaxy + 3b (mod 13N)
722  * = 3*(x^3 + a*x - y^2) + 3b (mod 13N)
723  * = 3*(x^3 + a*x + b - y^2) (mod 13N)
724  */
725  WEIERSTRASS_ADD2 ( Wt, 3b ),
726  /* [Wt] check = 3Txaxyb * z (mod 2N)
727  * = 3*(x^3 + a*x + b - y^2) * z (mod 2N)
728  */
729  WEIERSTRASS_MUL2 ( Wt, z1 ),
730  /* Stop */
732  };
733 
734  /* Initialise register list */
735  regs[WEIERSTRASS_a] = ( ( void * ) a );
736  regs[WEIERSTRASS_3b] = ( ( void * ) b3 );
737  regs[WEIERSTRASS_x1] = ( ( void * ) &point->x );
738  regs[WEIERSTRASS_y1] = ( ( void * ) &point->y );
739  regs[WEIERSTRASS_z1] = ( ( void * ) &point->z );
740  regs[WEIERSTRASS_Wt] = &temp.Wt;
741  regs[WEIERSTRASS_Wp] = &temp.Wp;
742 
743  /* Execute bytecode instruction sequence */
744  for ( op = ops ; *op != WEIERSTRASS_STOP ; op++ )
745  weierstrass_exec ( curve, regs, size, *op );
746 
747  /* Check that result is zero (modulo the field prime) */
748  bigint_grow ( &temp.Wt, &temp.Wp );
749  bigint_montgomery ( prime, &temp.Wp, &temp.Wt );
750  if ( ! bigint_is_zero ( &temp.Wt ) ) {
751  DBGC ( curve, "WEIERSTRASS %s base point is not on curve\n",
752  curve->name );
753  return -EINVAL;
754  }
755 
756  return 0;
757 }
#define __attribute__(x)
Definition: compiler.h:10
#define EINVAL
Invalid argument.
Definition: errno.h:428
unsigned short uint16_t
Definition: stdint.h:11
#define WEIERSTRASS_STOP
Define a stop operation.
Definition: weierstrass.c:158
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:108
static void weierstrass_exec(const struct weierstrass_curve *curve, void **regs, unsigned int size, unsigned int op)
Execute bytecode instruction.
Definition: weierstrass.c:267
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:208
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
bigint_element_t * b3
Cached constant "3b", in Montgomery form.
Definition: weierstrass.h:121
#define WEIERSTRASS_MOV(dest, source)
Define a move operation.
Definition: weierstrass.c:145
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
#define WEIERSTRASS_MUL3(dest, multiplicand, multiplier)
Define a three-argument multiplication operation.
Definition: weierstrass.c:161
bigint_element_t * a
Cached constant "a", in Montgomery form.
Definition: weierstrass.h:119
const char * name
Curve name.
Definition: weierstrass.h:95
#define WEIERSTRASS_SUB2(minuend, subtrahend, multiple)
Define a two-argument subtraction operation.
Definition: weierstrass.c:154
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:313
#define WEIERSTRASS_MUL2(multiplicand, multiplier)
Define a two-argument multiplication operation.
Definition: weierstrass.c:165
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
#define WEIERSTRASS_ADD3(dest, augend, addend)
Define a three-argument addition operation.
Definition: weierstrass.c:137
#define WEIERSTRASS_ADD2(augend, addend)
Define a two-argument addition operation.
Definition: weierstrass.c:141
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 779 of file weierstrass.c.

781  {
782  unsigned int size = curve->size;
783  size_t len = curve->len;
784  const bigint_t ( size ) __attribute__ (( may_alias )) *prime =
785  ( ( const void * ) curve->prime[0] );
786  const bigint_t ( size ) __attribute__ (( may_alias )) *prime2 =
787  ( ( const void * ) curve->prime[WEIERSTRASS_2N] );
788  const bigint_t ( size ) __attribute__ (( may_alias )) *square =
789  ( ( const void * ) curve->square );
790  const bigint_t ( size ) __attribute__ (( may_alias )) *one =
791  ( ( const void * ) curve->one );
792  weierstrass_t ( size ) __attribute__ (( may_alias ))
793  *point = ( ( void * ) point0 );
794  union {
795  bigint_t ( size * 2 ) product;
796  weierstrass_t ( size ) point;
797  } __attribute__ (( may_alias )) *temp = ( ( void * ) temp0 );
798  size_t offset;
799  int is_infinite;
800  unsigned int i;
801  int rc;
802 
803  /* Initialise curve, if not already done
804  *
805  * The least significant element of the field prime must be
806  * odd, and so the least significant element of the
807  * (initialised) first multiple of the field prime must be
808  * non-zero.
809  */
810  if ( ! prime2->element[0] )
811  weierstrass_init_curve ( curve );
812 
813  /* Convert input to projective coordinates in Montgomery form */
814  DBGC ( curve, "WEIERSTRASS %s point (", curve->name );
815  for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
816  bigint_init ( &point->axis[i], ( data + offset ), len );
817  DBGC ( curve, "%s%s", ( i ? "," : "" ),
818  bigint_ntoa ( &point->axis[i] ) );
819  bigint_multiply ( &point->axis[i], square, &temp->product );
820  bigint_montgomery_relaxed ( prime, &temp->product,
821  &point->axis[i] );
822  }
823  memset ( &point->z, 0, sizeof ( point->z ) );
824  is_infinite = bigint_is_zero ( &point->xy );
825  bigint_copy ( one, &point->axis[ is_infinite ? 1 : 2 ] );
826  DBGC ( curve, ")\n" );
827 
828  /* Verify point is on curve */
829  if ( ( rc = weierstrass_verify ( curve, point ) ) != 0 )
830  return rc;
831 
832  return 0;
833 }
#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:112
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:108
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:16
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
#define weierstrass_verify(curve, point)
Verify freshly initialised point is on curve.
Definition: weierstrass.c:766
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:299
static void weierstrass_init_curve(struct weierstrass_curve *curve)
Initialise curve.
Definition: weierstrass.c:173
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
ring len
Length.
Definition: dwmac.h:231
const char * name
Curve name.
Definition: weierstrass.h:95
size_t len
Length of raw scalar values.
Definition: weierstrass.h:97
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:117
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:259
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint8_t product
Product string.
Definition: smbios.h:16
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
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 857 of file weierstrass.c.

859  {
860  unsigned int size = curve->size;
861  size_t len = curve->len;
862  const bigint_t ( size ) __attribute__ (( may_alias )) *prime =
863  ( ( const void * ) curve->prime[0] );
864  const bigint_t ( size ) __attribute__ (( may_alias )) *fermat =
865  ( ( const void * ) curve->fermat );
866  const bigint_t ( size ) __attribute__ (( may_alias )) *one =
867  ( ( const void * ) curve->one );
868  weierstrass_t ( size ) __attribute__ (( may_alias ))
869  *point = ( ( void * ) point0 );
870  union {
871  bigint_t ( size * 2 ) product;
872  weierstrass_t ( size ) point;
873  } __attribute__ (( may_alias )) *temp = ( ( void * ) temp0 );
874  size_t offset;
875  unsigned int i;
876 
877  /* Invert result Z co-ordinate (via Fermat's little theorem) */
878  bigint_copy ( one, &temp->point.z );
879  bigint_ladder ( &temp->point.z, &point->z, fermat,
880  bigint_mod_exp_ladder, prime, &temp->product );
881 
882  /* Convert result back to affine co-ordinates */
883  DBGC ( curve, "WEIERSTRASS %s result (", curve->name );
884  for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
885  bigint_multiply ( &point->axis[i], &temp->point.z,
886  &temp->product );
887  bigint_montgomery_relaxed ( prime, &temp->product,
888  &point->axis[i] );
889  bigint_grow ( &point->axis[i], &temp->product );
890  bigint_montgomery ( prime, &temp->product, &point->axis[i] );
891  DBGC ( curve, "%s%s", ( i ? "," : "" ),
892  bigint_ntoa ( &point->axis[i] ) );
893  bigint_done ( &point->axis[i], ( out + offset ), len );
894  }
895  DBGC ( curve, ")\n" );
896 }
#define __attribute__(x)
Definition: compiler.h:10
bigint_element_t * prime[WEIERSTRASS_NUM_CACHED]
Cached field prime "N" (and multiples thereof)
Definition: weierstrass.h:108
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:16
#define DBGC(...)
Definition: compiler.h:505
#define bigint_grow(source, dest)
Grow big integer.
Definition: bigint.h:208
#define bigint_montgomery_relaxed(modulus, value, result)
Perform relaxed Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:299
__be32 out[4]
Definition: CIB_PRM.h:36
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
ring len
Length.
Definition: dwmac.h:231
bigint_element_t * fermat
Cached constant "N-2" (for Fermat's little theorem)
Definition: weierstrass.h:110
#define bigint_done(value, out, len)
Finalise big integer.
Definition: bigint.h:74
const char * name
Curve name.
Definition: weierstrass.h:95
size_t len
Length of raw scalar values.
Definition: weierstrass.h:97
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:117
#define bigint_montgomery(modulus, value, result)
Perform classic Montgomery reduction (REDC) of a big integer.
Definition: bigint.h:313
#define bigint_multiply(multiplicand, multiplier, result)
Multiply big integers.
Definition: bigint.h:259
uint8_t product
Product string.
Definition: smbios.h:16
#define bigint_ladder(result, multiple, exponent, op, ctx, tmp)
Perform generalised exponentiation via a Montgomery ladder.
Definition: bigint.h:329
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
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:719

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 918 of file weierstrass.c.

919  {
920  unsigned int size = curve->size;
921  size_t len = curve->len;
922  struct {
923  bigint_t ( size ) axis;
924  } temp;
925  size_t offset;
926  int is_finite = 0;
927  unsigned int i;
928 
929  /* We use all zeroes to represent the point at infinity */
930  DBGC ( curve, "WEIERSTRASS %s point (", curve->name );
931  for ( i = 0, offset = 0 ; i < WEIERSTRASS_AXES ; i++, offset += len ) {
932  bigint_init ( &temp.axis, ( point + offset ), len );
933  DBGC ( curve, "%s%s", ( i ? "," : "" ),
934  bigint_ntoa ( &temp.axis ) );
935  is_finite |= ( ! bigint_is_zero ( &temp.axis ) );
936  }
937  DBGC ( curve, ") is%s infinity\n", ( is_finite ? " not" : "" ) );
938 
939  return ( ! is_finite );
940 }
uint16_t size
Buffer size.
Definition: dwmac.h:14
#define WEIERSTRASS_AXES
Number of axes in Weierstrass curve point representation.
Definition: weierstrass.h:16
#define DBGC(...)
Definition: compiler.h:505
#define bigint_init(value, data, len)
Initialise big integer.
Definition: bigint.h:61
#define bigint_is_zero(value)
Test if big integer is equal to zero.
Definition: bigint.h:133
ring len
Length.
Definition: dwmac.h:231
const char * name
Curve name.
Definition: weierstrass.h:95
size_t len
Length of raw scalar values.
Definition: weierstrass.h:97
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
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 951 of file weierstrass.c.

952  {
953  unsigned int size = curve->size;
954  size_t len = curve->len;
955  const bigint_t ( size ) __attribute__ (( may_alias )) *one =
956  ( ( const void * ) curve->one );
957  struct {
959  weierstrass_t ( size ) multiple;
960  bigint_t ( bigint_required_size ( len ) ) scalar;
961  } temp;
962  int rc;
963 
964  /* Convert input to projective coordinates in Montgomery form */
965  if ( ( rc = weierstrass_init ( curve, &temp.multiple, &temp.result,
966  base ) ) != 0 ) {
967  return rc;
968  }
969 
970  /* Construct identity element (the point at infinity) */
971  memset ( &temp.result, 0, sizeof ( temp.result ) );
972  bigint_copy ( one, &temp.result.y );
973 
974  /* Initialise scalar */
975  bigint_init ( &temp.scalar, scalar, len );
976  DBGC ( curve, "WEIERSTRASS %s scalar %s\n",
977  curve->name, bigint_ntoa ( &temp.scalar ) );
978 
979  /* Perform multiplication via Montgomery ladder */
980  bigint_ladder ( &temp.result.all, &temp.multiple.all, &temp.scalar,
981  weierstrass_add_ladder, curve, NULL );
982 
983  /* Convert result back to affine co-ordinates */
984  weierstrass_done ( curve, &temp.result, &temp.multiple, result );
985 
986  return 0;
987 }
#define weierstrass_init(curve, point, temp, data)
Initialise curve point.
Definition: weierstrass.c:844
#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:61
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:644
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
#define weierstrass_done(curve, point, temp, out)
Finalise curve point.
Definition: weierstrass.c:907
#define bigint_copy(source, dest)
Copy big integer.
Definition: bigint.h:234
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:30
const char * name
Curve name.
Definition: weierstrass.h:95
size_t len
Length of raw scalar values.
Definition: weierstrass.h:97
bigint_element_t * one
Cached constant "1", in Montgomery form.
Definition: weierstrass.h:117
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:329
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93
#define bigint_ntoa(value)
Transcribe big integer (for debugging)
Definition: bigint.h:49
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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 998 of file weierstrass.c.

1000  {
1001  unsigned int size = curve->size;
1002  struct {
1003  weierstrass_t ( size ) addend;
1004  weierstrass_t ( size ) augend;
1006  } temp;
1007  int rc;
1008 
1009  /* Convert inputs to projective coordinates in Montgomery form */
1010  if ( ( rc = weierstrass_init ( curve, &temp.addend, &temp.result,
1011  addend ) ) != 0 ) {
1012  return rc;
1013  }
1014  if ( ( rc = weierstrass_init ( curve, &temp.augend, &temp.result,
1015  augend ) ) != 0 ) {
1016  return rc;
1017  }
1018 
1019  /* Add curve points */
1020  weierstrass_add ( curve, &temp.augend, &temp.addend, &temp.result );
1021 
1022  /* Convert result back to affine co-ordinates */
1023  weierstrass_done ( curve, &temp.result, &temp.addend, result );
1024 
1025  return 0;
1026 }
#define weierstrass_init(curve, point, temp, data)
Initialise curve point.
Definition: weierstrass.c:844
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:629
#define weierstrass_t(size)
Define a Weierstrass projective co-ordinate type.
Definition: weierstrass.h:57
#define weierstrass_done(curve, point, temp, out)
Finalise curve point.
Definition: weierstrass.c:907
uint16_t result
Definition: hyperv.h:33
const unsigned int size
Number of elements in scalar values.
Definition: weierstrass.h:93

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