PRCYCoin  2.0.0.7rc1
P2P Digital Currency
field_gmp_impl.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (c) 2013, 2014 Pieter Wuille *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef _SECP256K1_FIELD_REPR_IMPL_H_
8 #define _SECP256K1_FIELD_REPR_IMPL_H_
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include "num.h"
13 #include "field.h"
14 
15 static mp_limb_t secp256k1_field_p[FIELD_LIMBS];
16 static mp_limb_t secp256k1_field_pc[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
17 
18 static void secp256k1_fe_inner_start(void) {
19  for (int i=0; i<(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; i++)
20  secp256k1_field_pc[i] = 0;
21  secp256k1_field_pc[0] += 0x3D1UL;
22  secp256k1_field_pc[32/GMP_NUMB_BITS] += (((mp_limb_t)1) << (32 % GMP_NUMB_BITS));
23  for (int i=0; i<FIELD_LIMBS; i++) {
24  secp256k1_field_p[i] = 0;
25  }
26  mpn_sub(secp256k1_field_p, secp256k1_field_p, FIELD_LIMBS, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
27 }
28 
29 static void secp256k1_fe_inner_stop(void) {
30 }
31 
32 static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
33  if (r->n[FIELD_LIMBS] != 0) {
34 #if (GMP_NUMB_BITS >= 40)
35  mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * r->n[FIELD_LIMBS]);
36  mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x1000003D1ULL * carry);
37 #else
38  mp_limb_t carry = mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * r->n[FIELD_LIMBS]) +
39  mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), r->n[FIELD_LIMBS] << (32 % GMP_NUMB_BITS));
40  mpn_add_1(r->n, r->n, FIELD_LIMBS, 0x3D1UL * carry);
41  mpn_add_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), carry << (32%GMP_NUMB_BITS));
42 #endif
43  r->n[FIELD_LIMBS] = 0;
44  }
45  if (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) >= 0)
46  mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS);
47 }
48 
49 SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
50  r->n[0] = a;
51  for (int i=1; i<FIELD_LIMBS+1; i++)
52  r->n[i] = 0;
53 }
54 
55 SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *r) {
56  for (int i=0; i<FIELD_LIMBS+1; i++)
57  r->n[i] = 0;
58 }
59 
60 SECP256K1_INLINE static int secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
61  int ret = 1;
62  for (int i=0; i<FIELD_LIMBS+1; i++)
63  ret &= (a->n[i] == 0);
64  return ret;
65 }
66 
67 SECP256K1_INLINE static int secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
68  return a->n[0] & 1;
69 }
70 
71 SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
72  int ret = 1;
73  for (int i=0; i<FIELD_LIMBS+1; i++)
74  ret &= (a->n[i] == b->n[i]);
75  return ret;
76 }
77 
78 SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
79  for (int i=FIELD_LIMBS; i>=0; i--) {
80  if (a->n[i] > b->n[i]) return 1;
81  if (a->n[i] < b->n[i]) return -1;
82  }
83  return 0;
84 }
85 
86 static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
87  for (int i=0; i<FIELD_LIMBS+1; i++)
88  r->n[i] = 0;
89  for (int i=0; i<256; i++) {
90  int limb = i/GMP_NUMB_BITS;
91  int shift = i%GMP_NUMB_BITS;
92  r->n[limb] |= (mp_limb_t)((a[31-i/8] >> (i%8)) & 0x1) << shift;
93  }
94  return (mpn_cmp(r->n, secp256k1_field_p, FIELD_LIMBS) < 0);
95 }
96 
98 static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
99  for (int i=0; i<32; i++) {
100  int c = 0;
101  for (int j=0; j<8; j++) {
102  int limb = (8*i+j)/GMP_NUMB_BITS;
103  int shift = (8*i+j)%GMP_NUMB_BITS;
104  c |= ((a->n[limb] >> shift) & 0x1) << j;
105  }
106  r[31-i] = c;
107  }
108 }
109 
110 SECP256K1_INLINE static void secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
111  (void)m;
112  *r = *a;
113  secp256k1_fe_normalize(r);
114  for (int i=0; i<FIELD_LIMBS; i++)
115  r->n[i] = ~(r->n[i]);
116 #if (GMP_NUMB_BITS >= 33)
117  mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x1000003D0ULL);
118 #else
119  mpn_sub_1(r->n, r->n, FIELD_LIMBS, 0x3D0UL);
120  mpn_sub_1(r->n+(32/GMP_NUMB_BITS), r->n+(32/GMP_NUMB_BITS), FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
121 #endif
122 }
123 
124 SECP256K1_INLINE static void secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
125  mpn_mul_1(r->n, r->n, FIELD_LIMBS+1, a);
126 }
127 
128 SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
129  mpn_add(r->n, r->n, FIELD_LIMBS+1, a->n, FIELD_LIMBS+1);
130 }
131 
132 static void secp256k1_fe_reduce(secp256k1_fe_t *r, mp_limb_t *tmp) {
139 #if (GMP_NUMB_BITS >= 33)
140  mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x1000003D1ULL);
141 #else
142  mp_limb_t o = mpn_addmul_1(tmp, tmp+FIELD_LIMBS, FIELD_LIMBS, 0x3D1UL) +
143  mpn_addmul_1(tmp+(32/GMP_NUMB_BITS), tmp+FIELD_LIMBS, FIELD_LIMBS-(32/GMP_NUMB_BITS), 0x1UL << (32%GMP_NUMB_BITS));
144 #endif
145  mp_limb_t q[1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS];
146  q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] = mpn_mul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o);
147 #if (GMP_NUMB_BITS <= 32)
148  mp_limb_t o2 = tmp[2*FIELD_LIMBS-(32/GMP_NUMB_BITS)] << (32%GMP_NUMB_BITS);
149  q[(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS] += mpn_addmul_1(q, secp256k1_field_pc, (33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS, o2);
150 #endif
151  r->n[FIELD_LIMBS] = mpn_add(r->n, tmp, FIELD_LIMBS, q, 1+(33+GMP_NUMB_BITS-1)/GMP_NUMB_BITS);
152 }
153 
154 static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
155  VERIFY_CHECK(r != b);
156  secp256k1_fe_t ac = *a;
157  secp256k1_fe_t bc = *b;
158  secp256k1_fe_normalize(&ac);
159  secp256k1_fe_normalize(&bc);
160  mp_limb_t tmp[2*FIELD_LIMBS];
161  mpn_mul_n(tmp, ac.n, bc.n, FIELD_LIMBS);
162  secp256k1_fe_reduce(r, tmp);
163 }
164 
165 static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
166  secp256k1_fe_t ac = *a;
167  secp256k1_fe_normalize(&ac);
168  mp_limb_t tmp[2*FIELD_LIMBS];
169  mpn_sqr(tmp, ac.n, FIELD_LIMBS);
170  secp256k1_fe_reduce(r, tmp);
171 }
172 
173 static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
174  mp_limb_t mask0 = flag + ~((mp_limb_t)0), mask1 = ~mask0;
175  for (int i = 0; i <= FIELD_LIMBS; i++) {
176  r->n[i] = (r->n[i] & mask0) | (a->n[i] & mask1);
177  }
178 }
179 
180 #endif
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition: util.h:61
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
SECP256K1_RESTRICT
#define SECP256K1_RESTRICT
Definition: util.h:74
secp256k1_fe_t::n
uint32_t n[10]
Definition: field_10x26.h:18
r
void const uint64_t uint64_t * r
Definition: field_5x52_asm_impl.h:10
FIELD_LIMBS
#define FIELD_LIMBS
Definition: field_gmp.h:12
secp256k1_fe_t
Definition: field_10x26.h:12
num.h
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition: secp256k1.h:23
field.h