github.com/cloudflare/circl@v1.5.0/dh/x448/curve.go (about)

     1  package x448
     2  
     3  import (
     4  	fp "github.com/cloudflare/circl/math/fp448"
     5  )
     6  
     7  // ladderJoye calculates a fixed-point multiplication with the generator point.
     8  // The algorithm is the right-to-left Joye's ladder as described
     9  // in "How to precompute a ladder" in SAC'2017.
    10  func ladderJoye(k *Key) {
    11  	w := [5]fp.Elt{} // [mu,x1,z1,x2,z2] order must be preserved.
    12  	w[1] = fp.Elt{   // x1 = S
    13  		0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    14  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    15  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    16  		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
    17  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    18  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    19  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    20  	}
    21  	fp.SetOne(&w[2]) // z1 = 1
    22  	w[3] = fp.Elt{   // x2 = G-S
    23  		0x20, 0x27, 0x9d, 0xc9, 0x7d, 0x19, 0xb1, 0xac,
    24  		0xf8, 0xba, 0x69, 0x1c, 0xff, 0x33, 0xac, 0x23,
    25  		0x51, 0x1b, 0xce, 0x3a, 0x64, 0x65, 0xbd, 0xf1,
    26  		0x23, 0xf8, 0xc1, 0x84, 0x9d, 0x45, 0x54, 0x29,
    27  		0x67, 0xb9, 0x81, 0x1c, 0x03, 0xd1, 0xcd, 0xda,
    28  		0x7b, 0xeb, 0xff, 0x1a, 0x88, 0x03, 0xcf, 0x3a,
    29  		0x42, 0x44, 0x32, 0x01, 0x25, 0xb7, 0xfa, 0xf0,
    30  	}
    31  	fp.SetOne(&w[4]) // z2 = 1
    32  
    33  	const n = 448
    34  	const h = 2
    35  	swap := uint(1)
    36  	for s := 0; s < n-h; s++ {
    37  		i := (s + h) / 8
    38  		j := (s + h) % 8
    39  		bit := uint((k[i] >> uint(j)) & 1)
    40  		copy(w[0][:], tableGenerator[s*Size:(s+1)*Size])
    41  		diffAdd(&w, swap^bit)
    42  		swap = bit
    43  	}
    44  	for s := 0; s < h; s++ {
    45  		double(&w[1], &w[2])
    46  	}
    47  	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
    48  }
    49  
    50  // ladderMontgomery calculates a generic scalar point multiplication
    51  // The algorithm implemented is the left-to-right Montgomery's ladder.
    52  func ladderMontgomery(k, xP *Key) {
    53  	w := [5]fp.Elt{}      // [x1, x2, z2, x3, z3] order must be preserved.
    54  	w[0] = *(*fp.Elt)(xP) // x1 = xP
    55  	fp.SetOne(&w[1])      // x2 = 1
    56  	w[3] = *(*fp.Elt)(xP) // x3 = xP
    57  	fp.SetOne(&w[4])      // z3 = 1
    58  
    59  	move := uint(0)
    60  	for s := 448 - 1; s >= 0; s-- {
    61  		i := s / 8
    62  		j := s % 8
    63  		bit := uint((k[i] >> uint(j)) & 1)
    64  		ladderStep(&w, move^bit)
    65  		move = bit
    66  	}
    67  	toAffine((*[fp.Size]byte)(k), &w[1], &w[2])
    68  }
    69  
    70  func toAffine(k *[fp.Size]byte, x, z *fp.Elt) {
    71  	fp.Inv(z, z)
    72  	fp.Mul(x, x, z)
    73  	_ = fp.ToBytes(k[:], x)
    74  }
    75  
    76  var lowOrderPoints = [3]fp.Elt{
    77  	{ /* (0,_,1) point of order 2 on Curve448 */
    78  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    79  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    80  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    81  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    82  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    83  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    84  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    85  	},
    86  	{ /* (1,_,1) a point of order 4 on the twist of Curve448 */
    87  		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    88  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    89  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    90  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    91  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    92  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    93  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    94  	},
    95  	{ /* (-1,_,1) point of order 4 on Curve448 */
    96  		0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    97  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    98  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    99  		0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff,
   100  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   101  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   102  		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
   103  	},
   104  }