kpqc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +174 -0
- data/Rakefile +57 -0
- data/THIRD_PARTY_NOTICES.md +53 -0
- data/ext/kpqc/aimer128f/extconf.rb +4 -0
- data/ext/kpqc/aimer128s/extconf.rb +4 -0
- data/ext/kpqc/aimer192f/extconf.rb +4 -0
- data/ext/kpqc/aimer192s/extconf.rb +4 -0
- data/ext/kpqc/aimer256f/extconf.rb +4 -0
- data/ext/kpqc/aimer256s/extconf.rb +4 -0
- data/ext/kpqc/extconf_helper.rb +93 -0
- data/ext/kpqc/haetae2/extconf.rb +4 -0
- data/ext/kpqc/haetae3/extconf.rb +4 -0
- data/ext/kpqc/haetae5/extconf.rb +4 -0
- data/ext/kpqc/module.c +195 -0
- data/ext/kpqc/ntruplus1152/extconf.rb +4 -0
- data/ext/kpqc/ntruplus768/extconf.rb +4 -0
- data/ext/kpqc/ntruplus864/extconf.rb +4 -0
- data/ext/kpqc/randombytes.c +107 -0
- data/ext/kpqc/smaugt128/extconf.rb +4 -0
- data/ext/kpqc/smaugt192/extconf.rb +4 -0
- data/ext/kpqc/smaugt256/extconf.rb +4 -0
- data/ext/kpqc/timer/extconf.rb +4 -0
- data/kpqc.gemspec +41 -0
- data/lib/kpqc/aimer.rb +38 -0
- data/lib/kpqc/api.rb +129 -0
- data/lib/kpqc/haetae.rb +25 -0
- data/lib/kpqc/ntruplus.rb +25 -0
- data/lib/kpqc/smaugt.rb +29 -0
- data/lib/kpqc/types.rb +103 -0
- data/lib/kpqc/version.rb +6 -0
- data/lib/kpqc.rb +33 -0
- data/test/algorithm_test.rb +111 -0
- data/test/api_test.rb +52 -0
- data/test/interop.mjs +34 -0
- data/test/interop_test.rb +82 -0
- data/test/kat/aimer128f.rsp +10 -0
- data/test/kat/aimer128s.rsp +10 -0
- data/test/kat/aimer192f.rsp +10 -0
- data/test/kat/aimer192s.rsp +10 -0
- data/test/kat/aimer256f.rsp +10 -0
- data/test/kat/aimer256s.rsp +10 -0
- data/test/kat/haetae2.rsp +10 -0
- data/test/kat/haetae3.rsp +10 -0
- data/test/kat/haetae5.rsp +10 -0
- data/test/kat/ntruplus1152.rsp +8 -0
- data/test/kat/ntruplus768.rsp +8 -0
- data/test/kat/ntruplus864.rsp +8 -0
- data/test/kat/smaugt128.rsp +8 -0
- data/test/kat/smaugt192.rsp +8 -0
- data/test/kat/smaugt256.rsp +8 -0
- data/test/kat/timer.rsp +8 -0
- data/test/kat_drbg.rb +155 -0
- data/test/kat_test.rb +99 -0
- data/test/test_helper.rb +21 -0
- data/vendor/AIMer/LICENSE +21 -0
- data/vendor/AIMer/aim2.c +163 -0
- data/vendor/AIMer/aim2.h +36 -0
- data/vendor/AIMer/aim2_constant.h +74 -0
- data/vendor/AIMer/api.h +42 -0
- data/vendor/AIMer/common/crypto_declassify.h +7 -0
- data/vendor/AIMer/common/fips202.c +878 -0
- data/vendor/AIMer/common/fips202.h +166 -0
- data/vendor/AIMer/common/rng.h +56 -0
- data/vendor/AIMer/field.h +43 -0
- data/vendor/AIMer/field128.c +454 -0
- data/vendor/AIMer/field192.c +485 -0
- data/vendor/AIMer/field256.c +564 -0
- data/vendor/AIMer/hash.c +50 -0
- data/vendor/AIMer/hash.h +37 -0
- data/vendor/AIMer/params/params-aimer-128f.h +34 -0
- data/vendor/AIMer/params/params-aimer-128s.h +34 -0
- data/vendor/AIMer/params/params-aimer-192f.h +34 -0
- data/vendor/AIMer/params/params-aimer-192s.h +34 -0
- data/vendor/AIMer/params/params-aimer-256f.h +34 -0
- data/vendor/AIMer/params/params-aimer-256s.h +34 -0
- data/vendor/AIMer/params.h +5 -0
- data/vendor/AIMer/sign.c +631 -0
- data/vendor/AIMer/sign.h +40 -0
- data/vendor/AIMer/tree.c +75 -0
- data/vendor/AIMer/tree.h +26 -0
- data/vendor/HAETAE/LICENSE +22 -0
- data/vendor/HAETAE/include/api.h +54 -0
- data/vendor/HAETAE/include/common.h +12 -0
- data/vendor/HAETAE/include/config.h +42 -0
- data/vendor/HAETAE/include/decompose.h +19 -0
- data/vendor/HAETAE/include/encoding.h +20 -0
- data/vendor/HAETAE/include/fft.h +26 -0
- data/vendor/HAETAE/include/fips202.h +40 -0
- data/vendor/HAETAE/include/fixpoint.h +125 -0
- data/vendor/HAETAE/include/ntt.h +16 -0
- data/vendor/HAETAE/include/packing.h +58 -0
- data/vendor/HAETAE/include/params.h +117 -0
- data/vendor/HAETAE/include/poly.h +65 -0
- data/vendor/HAETAE/include/polyfix.h +65 -0
- data/vendor/HAETAE/include/polymat.h +32 -0
- data/vendor/HAETAE/include/polyvec.h +131 -0
- data/vendor/HAETAE/include/randombytes.h +39 -0
- data/vendor/HAETAE/include/rans_byte.h +335 -0
- data/vendor/HAETAE/include/reduce.h +31 -0
- data/vendor/HAETAE/include/sampler.h +23 -0
- data/vendor/HAETAE/include/symmetric.h +52 -0
- data/vendor/HAETAE/src/decompose.c +73 -0
- data/vendor/HAETAE/src/encoding.c +700 -0
- data/vendor/HAETAE/src/fft.c +235 -0
- data/vendor/HAETAE/src/fips202.c +745 -0
- data/vendor/HAETAE/src/fixpoint.c +143 -0
- data/vendor/HAETAE/src/ntt.c +98 -0
- data/vendor/HAETAE/src/packing.c +595 -0
- data/vendor/HAETAE/src/poly.c +371 -0
- data/vendor/HAETAE/src/polyfix.c +298 -0
- data/vendor/HAETAE/src/polymat.c +82 -0
- data/vendor/HAETAE/src/polyvec.c +534 -0
- data/vendor/HAETAE/src/reduce.c +96 -0
- data/vendor/HAETAE/src/sampler.c +310 -0
- data/vendor/HAETAE/src/sign.c +558 -0
- data/vendor/HAETAE/src/symmetric-shake.c +50 -0
- data/vendor/NTRUplus/LICENSE +21 -0
- data/vendor/NTRUplus/NTRU+1152/api.h +24 -0
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+1152/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+1152/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+1152/ntt.c +394 -0
- data/vendor/NTRUplus/NTRU+1152/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+1152/params.h +18 -0
- data/vendor/NTRUplus/NTRU+1152/poly.c +318 -0
- data/vendor/NTRUplus/NTRU+1152/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+1152/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+1152/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+1152/symmetric.h +12 -0
- data/vendor/NTRUplus/NTRU+768/api.h +24 -0
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+768/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+768/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+768/ntt.c +379 -0
- data/vendor/NTRUplus/NTRU+768/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+768/params.h +18 -0
- data/vendor/NTRUplus/NTRU+768/poly.c +320 -0
- data/vendor/NTRUplus/NTRU+768/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+768/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+768/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+768/symmetric.h +12 -0
- data/vendor/NTRUplus/NTRU+864/api.h +24 -0
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.c +878 -0
- data/vendor/NTRUplus/NTRU+864/fips202/fips202.h +166 -0
- data/vendor/NTRUplus/NTRU+864/kem.c +286 -0
- data/vendor/NTRUplus/NTRU+864/ntt.c +383 -0
- data/vendor/NTRUplus/NTRU+864/ntt.h +16 -0
- data/vendor/NTRUplus/NTRU+864/params.h +18 -0
- data/vendor/NTRUplus/NTRU+864/poly.c +314 -0
- data/vendor/NTRUplus/NTRU+864/poly.h +31 -0
- data/vendor/NTRUplus/NTRU+864/randombytes.h +9 -0
- data/vendor/NTRUplus/NTRU+864/symmetric.c +39 -0
- data/vendor/NTRUplus/NTRU+864/symmetric.h +12 -0
- data/vendor/SMAUG-T/LICENSE +22 -0
- data/vendor/SMAUG-T/include/api.h +37 -0
- data/vendor/SMAUG-T/include/cbd.h +15 -0
- data/vendor/SMAUG-T/include/ciphertext.h +45 -0
- data/vendor/SMAUG-T/include/common.h +12 -0
- data/vendor/SMAUG-T/include/config.h +48 -0
- data/vendor/SMAUG-T/include/dg.h +28 -0
- data/vendor/SMAUG-T/include/fips202.h +41 -0
- data/vendor/SMAUG-T/include/hash.h +21 -0
- data/vendor/SMAUG-T/include/hwt.h +28 -0
- data/vendor/SMAUG-T/include/indcpa.h +33 -0
- data/vendor/SMAUG-T/include/key.h +34 -0
- data/vendor/SMAUG-T/include/pack.h +78 -0
- data/vendor/SMAUG-T/include/packring.h +50 -0
- data/vendor/SMAUG-T/include/params.h +84 -0
- data/vendor/SMAUG-T/include/poly.h +41 -0
- data/vendor/SMAUG-T/include/randombytes.h +11 -0
- data/vendor/SMAUG-T/include/toomcook.h +14 -0
- data/vendor/SMAUG-T/include/verify.h +16 -0
- data/vendor/SMAUG-T/src/cbd.c +159 -0
- data/vendor/SMAUG-T/src/ciphertext.c +95 -0
- data/vendor/SMAUG-T/src/dg.c +112 -0
- data/vendor/SMAUG-T/src/fips202.c +745 -0
- data/vendor/SMAUG-T/src/hash.c +15 -0
- data/vendor/SMAUG-T/src/hwt.c +121 -0
- data/vendor/SMAUG-T/src/indcpa.c +187 -0
- data/vendor/SMAUG-T/src/kem.c +194 -0
- data/vendor/SMAUG-T/src/key.c +102 -0
- data/vendor/SMAUG-T/src/pack.c +349 -0
- data/vendor/SMAUG-T/src/packring.c +503 -0
- data/vendor/SMAUG-T/src/poly.c +200 -0
- data/vendor/SMAUG-T/src/toomcook.c +256 -0
- data/vendor/SMAUG-T/src/verify.c +48 -0
- data/vendor/SOURCES.json +130 -0
- metadata +280 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#ifndef HAETAE_POLY_H
|
|
4
|
+
#define HAETAE_POLY_H
|
|
5
|
+
|
|
6
|
+
#include "params.h"
|
|
7
|
+
|
|
8
|
+
#include <stdint.h>
|
|
9
|
+
|
|
10
|
+
typedef struct {
|
|
11
|
+
int32_t coeffs[HAETAE_N];
|
|
12
|
+
} poly;
|
|
13
|
+
|
|
14
|
+
#define poly_add HAETAE_NAMESPACE(poly_add)
|
|
15
|
+
void poly_add(poly *c, const poly *a, const poly *b);
|
|
16
|
+
#define poly_sub HAETAE_NAMESPACE(poly_sub)
|
|
17
|
+
void poly_sub(poly *c, const poly *a, const poly *b);
|
|
18
|
+
#define poly_pointwise_montgomery HAETAE_NAMESPACE(poly_pointwise_montgomery)
|
|
19
|
+
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b);
|
|
20
|
+
|
|
21
|
+
#define poly_reduce2q HAETAE_NAMESPACE(poly_reduce2q)
|
|
22
|
+
void poly_reduce2q(poly *a);
|
|
23
|
+
#define poly_freeze2q HAETAE_NAMESPACE(poly_freeze2q)
|
|
24
|
+
void poly_freeze2q(poly *a);
|
|
25
|
+
#define poly_freeze HAETAE_NAMESPACE(poly_freeze)
|
|
26
|
+
void poly_freeze(poly *a);
|
|
27
|
+
|
|
28
|
+
#define poly_highbits HAETAE_NAMESPACE(poly_highbits)
|
|
29
|
+
void poly_highbits(poly *a2, const poly *a);
|
|
30
|
+
#define poly_lowbits HAETAE_NAMESPACE(poly_lowbits)
|
|
31
|
+
void poly_lowbits(poly *a1, const poly *a);
|
|
32
|
+
#define poly_compose HAETAE_NAMESPACE(poly_compose)
|
|
33
|
+
void poly_compose(poly *a, const poly *ha, const poly *la);
|
|
34
|
+
#define poly_lsb HAETAE_NAMESPACE(poly_lsb)
|
|
35
|
+
void poly_lsb(poly *a0, const poly *a);
|
|
36
|
+
|
|
37
|
+
#define poly_uniform HAETAE_NAMESPACE(poly_uniform)
|
|
38
|
+
void poly_uniform(poly *a, const uint8_t seed[HAETAE_SEEDBYTES],
|
|
39
|
+
uint16_t nonce);
|
|
40
|
+
#define poly_uniform_eta HAETAE_NAMESPACE(poly_uniform_eta)
|
|
41
|
+
void poly_uniform_eta(poly *a, const uint8_t seed[HAETAE_CRHBYTES],
|
|
42
|
+
uint16_t nonce);
|
|
43
|
+
#define poly_challenge HAETAE_NAMESPACE(poly_challenge)
|
|
44
|
+
void poly_challenge(
|
|
45
|
+
poly *c,
|
|
46
|
+
const uint8_t highbits_lsb[HAETAE_POLYVECK_HIGHBITS_PACKEDBYTES +
|
|
47
|
+
HAETAE_POLYC_PACKEDBYTES],
|
|
48
|
+
const uint8_t mu[HAETAE_SEEDBYTES]);
|
|
49
|
+
|
|
50
|
+
#define poly_decomposed_pack HAETAE_NAMESPACE(poly_decomposed_pack)
|
|
51
|
+
void poly_decomposed_pack(uint8_t *buf, const poly *a);
|
|
52
|
+
#define poly_decomposed_unpack HAETAE_NAMESPACE(poly_decomposed_unpack)
|
|
53
|
+
void poly_decomposed_unpack(poly *a, const uint8_t *buf);
|
|
54
|
+
|
|
55
|
+
#define poly_fromcrt HAETAE_NAMESPACE(poly_fromcrt)
|
|
56
|
+
void poly_fromcrt(poly *w, const poly *u, const poly *v);
|
|
57
|
+
#define poly_fromcrt0 HAETAE_NAMESPACE(poly_fromcrt0)
|
|
58
|
+
void poly_fromcrt0(poly *w, const poly *u);
|
|
59
|
+
|
|
60
|
+
#define poly_ntt HAETAE_NAMESPACE(poly_ntt)
|
|
61
|
+
void poly_ntt(poly *a);
|
|
62
|
+
#define poly_invntt_tomont HAETAE_NAMESPACE(poly_invntt_tomont)
|
|
63
|
+
void poly_invntt_tomont(poly *a);
|
|
64
|
+
|
|
65
|
+
#endif /* !HAETAE_POLY_H */
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#ifndef HAETAE_POLYFIX_H
|
|
4
|
+
#define HAETAE_POLYFIX_H
|
|
5
|
+
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "poly.h"
|
|
8
|
+
#include "polyvec.h"
|
|
9
|
+
|
|
10
|
+
#include <stdint.h>
|
|
11
|
+
|
|
12
|
+
typedef struct {
|
|
13
|
+
int32_t coeffs[HAETAE_N];
|
|
14
|
+
} polyfix;
|
|
15
|
+
|
|
16
|
+
#define polyfix_norm2 HAETAE_NAMESPACE(polyfix_norm2)
|
|
17
|
+
double polyfix_norm2(const polyfix *a);
|
|
18
|
+
|
|
19
|
+
#define polyfix_round HAETAE_NAMESPACE(polyfix_round)
|
|
20
|
+
void polyfix_round(poly *a, const polyfix *b);
|
|
21
|
+
|
|
22
|
+
#define polyfix_add HAETAE_NAMESPACE(polyfix_add)
|
|
23
|
+
void polyfix_add(polyfix *c, const polyfix *a, const poly *b);
|
|
24
|
+
|
|
25
|
+
typedef struct {
|
|
26
|
+
polyfix vec[HAETAE_K];
|
|
27
|
+
} polyfixveck;
|
|
28
|
+
|
|
29
|
+
#define polyfixveck_add HAETAE_NAMESPACE(polyfixveck_add)
|
|
30
|
+
void polyfixveck_add(polyfixveck *w, const polyfixveck *u, const polyveck *v);
|
|
31
|
+
#define polyfixfixveck_sub HAETAE_NAMESPACE(polyfixfixveck_sub)
|
|
32
|
+
void polyfixfixveck_sub(polyfixveck *w, const polyfixveck *u,
|
|
33
|
+
const polyfixveck *v);
|
|
34
|
+
#define polyfixveck_double HAETAE_NAMESPACE(polyfixveck_double)
|
|
35
|
+
void polyfixveck_double(polyfixveck *b, const polyfixveck *a);
|
|
36
|
+
|
|
37
|
+
#define polyfixveck_round HAETAE_NAMESPACE(polyfixveck_round)
|
|
38
|
+
void polyfixveck_round(polyveck *a, const polyfixveck *b);
|
|
39
|
+
|
|
40
|
+
typedef struct {
|
|
41
|
+
polyfix vec[HAETAE_L];
|
|
42
|
+
} polyfixvecl;
|
|
43
|
+
|
|
44
|
+
#define polyfixvecl_add HAETAE_NAMESPACE(polyfixvecl_add)
|
|
45
|
+
void polyfixvecl_add(polyfixvecl *w, const polyfixvecl *u, const polyvecl *v);
|
|
46
|
+
#define polyfixfixvecl_sub HAETAE_NAMESPACE(polyfixfixvecl_sub)
|
|
47
|
+
void polyfixfixvecl_sub(polyfixvecl *w, const polyfixvecl *u,
|
|
48
|
+
const polyfixvecl *v);
|
|
49
|
+
#define polyfixvecl_double HAETAE_NAMESPACE(polyfixvecl_double)
|
|
50
|
+
void polyfixvecl_double(polyfixvecl *b, const polyfixvecl *a);
|
|
51
|
+
|
|
52
|
+
#define polyfixvecl_round HAETAE_NAMESPACE(polyfixvecl_round)
|
|
53
|
+
void polyfixvecl_round(polyvecl *a, const polyfixvecl *b);
|
|
54
|
+
|
|
55
|
+
#define polyfixveclk_sqnorm2 HAETAE_NAMESPACE(polyfixveclk_sqnorm2)
|
|
56
|
+
uint64_t polyfixveclk_sqnorm2(const polyfixvecl *a, const polyfixveck *b);
|
|
57
|
+
|
|
58
|
+
#define polyfixveclk_sample_hyperball \
|
|
59
|
+
HAETAE_NAMESPACE(polyfixveclk_sample_hyperball)
|
|
60
|
+
uint16_t polyfixveclk_sample_hyperball(polyfixvecl *y1, polyfixveck *y2,
|
|
61
|
+
uint8_t *b,
|
|
62
|
+
const uint8_t seed[HAETAE_CRHBYTES],
|
|
63
|
+
const uint16_t nonce);
|
|
64
|
+
|
|
65
|
+
#endif /* !HAETAE_POLYFIX_H */
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#ifndef HAETAE_POLYMAT_H
|
|
4
|
+
#define HAETAE_POLYMAT_H
|
|
5
|
+
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "polyvec.h"
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
#define polymatkl_expand_matA HAETAE_NAMESPACE(polymatkl_expand_matA)
|
|
12
|
+
void polymatkl_expand_matA(polyvecl mat[HAETAE_K],
|
|
13
|
+
const uint8_t rho[HAETAE_SEEDBYTES]);
|
|
14
|
+
|
|
15
|
+
#define polymatkm_expand_matA HAETAE_NAMESPACE(polymatkm_expand_matA)
|
|
16
|
+
void polymatkm_expand_matA(polyvecm mat[HAETAE_K],
|
|
17
|
+
const uint8_t rho[HAETAE_SEEDBYTES]);
|
|
18
|
+
|
|
19
|
+
#define polymatkm_pointwise_montgomery \
|
|
20
|
+
HAETAE_NAMESPACE(polymatkm_pointwise_montgomery)
|
|
21
|
+
void polymatkm_pointwise_montgomery(polyveck *t, const polyvecm mat[HAETAE_K],
|
|
22
|
+
const polyvecm *v);
|
|
23
|
+
|
|
24
|
+
#define polymatkl_pointwise_montgomery \
|
|
25
|
+
HAETAE_NAMESPACE(polymatkl_pointwise_montgomery)
|
|
26
|
+
void polymatkl_pointwise_montgomery(polyveck *t, const polyvecl mat[HAETAE_K],
|
|
27
|
+
const polyvecl *v);
|
|
28
|
+
|
|
29
|
+
#define polymatkl_double HAETAE_NAMESPACE(polymatkl_double)
|
|
30
|
+
void polymatkl_double(polyvecl mat[HAETAE_K]);
|
|
31
|
+
|
|
32
|
+
#endif /* !HAETAE_POLYMAT_H */
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#ifndef HAETAE_POLYVEC_H
|
|
4
|
+
#define HAETAE_POLYVEC_H
|
|
5
|
+
|
|
6
|
+
#include "params.h"
|
|
7
|
+
#include "poly.h"
|
|
8
|
+
|
|
9
|
+
#include <stdint.h>
|
|
10
|
+
|
|
11
|
+
/* Vectors of polynomials of length HAETAE_K */
|
|
12
|
+
typedef struct {
|
|
13
|
+
poly vec[HAETAE_K];
|
|
14
|
+
} polyveck;
|
|
15
|
+
|
|
16
|
+
#define polyveck_add HAETAE_NAMESPACE(polyveck_add)
|
|
17
|
+
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v);
|
|
18
|
+
#define polyveck_sub HAETAE_NAMESPACE(polyveck_sub)
|
|
19
|
+
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v);
|
|
20
|
+
#define polyveck_double HAETAE_NAMESPACE(polyveck_double)
|
|
21
|
+
void polyveck_double(polyveck *b);
|
|
22
|
+
|
|
23
|
+
#define polyveck_reduce2q HAETAE_NAMESPACE(polyveck_reduce2q)
|
|
24
|
+
void polyveck_reduce2q(polyveck *v);
|
|
25
|
+
#define polyveck_freeze2q HAETAE_NAMESPACE(polyveck_freeze2q)
|
|
26
|
+
void polyveck_freeze2q(polyveck *v);
|
|
27
|
+
#define polyveck_freeze HAETAE_NAMESPACE(polyveck_freeze)
|
|
28
|
+
void polyveck_freeze(polyveck *v);
|
|
29
|
+
|
|
30
|
+
#define polyveck_uniform_eta HAETAE_NAMESPACE(polyveck_uniform_eta)
|
|
31
|
+
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[HAETAE_CRHBYTES],
|
|
32
|
+
uint16_t nonce);
|
|
33
|
+
#define polyveck_expand_vecA HAETAE_NAMESPACE(polyveck_expand_vecA)
|
|
34
|
+
void polyveck_expand_vecA(polyveck *v, const uint8_t seed[HAETAE_SEEDBYTES]);
|
|
35
|
+
|
|
36
|
+
#define polyveck_ntt HAETAE_NAMESPACE(polyveck_ntt)
|
|
37
|
+
void polyveck_ntt(polyveck *x);
|
|
38
|
+
|
|
39
|
+
#define polyveck_invntt_tomont HAETAE_NAMESPACE(polyveck_invntt_tomont)
|
|
40
|
+
void polyveck_invntt_tomont(polyveck *x);
|
|
41
|
+
|
|
42
|
+
#define polyveck_double_negate HAETAE_NAMESPACE(polyveck_double_negate)
|
|
43
|
+
void polyveck_double_negate(polyveck *x);
|
|
44
|
+
|
|
45
|
+
#define polyveck_frommont HAETAE_NAMESPACE(polyveck_frommont)
|
|
46
|
+
void polyveck_frommont(polyveck *x);
|
|
47
|
+
|
|
48
|
+
#define polyveck_poly_pointwise_montgomery \
|
|
49
|
+
HAETAE_NAMESPACE(polyveck_poly_pointwise_montgomery)
|
|
50
|
+
void polyveck_poly_pointwise_montgomery(polyveck *w, const polyveck *u,
|
|
51
|
+
const poly *v);
|
|
52
|
+
|
|
53
|
+
#define polyveck_poly_fromcrt HAETAE_NAMESPACE(polyveck_poly_fromcrt)
|
|
54
|
+
void polyveck_poly_fromcrt(polyveck *w, const polyveck *u, const poly *v);
|
|
55
|
+
|
|
56
|
+
#define polyveck_highbits_hint HAETAE_NAMESPACE(polyveck_highbits_hint)
|
|
57
|
+
void polyveck_highbits_hint(polyveck *w, const polyveck *v);
|
|
58
|
+
|
|
59
|
+
#define polyveck_cneg HAETAE_NAMESPACE(polyveck_cneg)
|
|
60
|
+
void polyveck_cneg(polyveck *v, const uint8_t b);
|
|
61
|
+
|
|
62
|
+
#define polyveck_caddDQ2ALPHA HAETAE_NAMESPACE(polyveck_caddDQ2ALPHA)
|
|
63
|
+
void polyveck_caddDQ2ALPHA(polyveck *h);
|
|
64
|
+
|
|
65
|
+
#define polyveck_csubDQ2ALPHA HAETAE_NAMESPACE(polyveck_csubDQ2ALPHA)
|
|
66
|
+
void polyveck_csubDQ2ALPHA(polyveck *v);
|
|
67
|
+
|
|
68
|
+
#define polyveck_mul_alpha HAETAE_NAMESPACE(polyveck_mul_alpha)
|
|
69
|
+
void polyveck_mul_alpha(polyveck *v, const polyveck *u);
|
|
70
|
+
|
|
71
|
+
#define polyveck_div2 HAETAE_NAMESPACE(polyveck_div2)
|
|
72
|
+
void polyveck_div2(polyveck *v);
|
|
73
|
+
|
|
74
|
+
#define polyveck_caddq HAETAE_NAMESPACE(polyveck_caddq)
|
|
75
|
+
void polyveck_caddq(polyveck *v);
|
|
76
|
+
|
|
77
|
+
#define polyveck_decompose_vk HAETAE_NAMESPACE(polyveck_decompose_vk)
|
|
78
|
+
void polyveck_decompose_vk(polyveck *v0, polyveck *v);
|
|
79
|
+
|
|
80
|
+
#define polyveck_sqnorm2 HAETAE_NAMESPACE(polyveck_sqnorm2)
|
|
81
|
+
uint64_t polyveck_sqnorm2(const polyveck *b);
|
|
82
|
+
|
|
83
|
+
/* Vectors of polynomials of length L */
|
|
84
|
+
typedef struct {
|
|
85
|
+
poly vec[HAETAE_L];
|
|
86
|
+
} polyvecl;
|
|
87
|
+
|
|
88
|
+
#define polyvecl_cneg HAETAE_NAMESPACE(polyvecl_cneg)
|
|
89
|
+
void polyvecl_cneg(polyvecl *v, const uint8_t b);
|
|
90
|
+
|
|
91
|
+
#define polyvecl_sqnorm2 HAETAE_NAMESPACE(polyvecl_sqnorm2)
|
|
92
|
+
uint64_t polyvecl_sqnorm2(const polyvecl *a);
|
|
93
|
+
|
|
94
|
+
#define polyvecl_ntt HAETAE_NAMESPACE(polyvecl_ntt)
|
|
95
|
+
void polyvecl_ntt(polyvecl *x);
|
|
96
|
+
|
|
97
|
+
#define polyvecl_highbits HAETAE_NAMESPACE(polyvecl_highbits)
|
|
98
|
+
void polyvecl_highbits(polyvecl *v2, const polyvecl *v);
|
|
99
|
+
#define polyvecl_lowbits HAETAE_NAMESPACE(polyvecl_lowbits)
|
|
100
|
+
void polyvecl_lowbits(polyvecl *v2, const polyvecl *v);
|
|
101
|
+
|
|
102
|
+
#define polyvecl_pointwise_acc_montgomery \
|
|
103
|
+
HAETAE_NAMESPACE(polyvecl_pointwise_acc_montgomery)
|
|
104
|
+
void polyvecl_pointwise_acc_montgomery(poly *w, const polyvecl *u,
|
|
105
|
+
const polyvecl *v);
|
|
106
|
+
|
|
107
|
+
/* Vectors of polynomials of length M */
|
|
108
|
+
typedef struct {
|
|
109
|
+
poly vec[HAETAE_M];
|
|
110
|
+
} polyvecm;
|
|
111
|
+
|
|
112
|
+
#define polyvecm_ntt HAETAE_NAMESPACE(polyvecm_ntt)
|
|
113
|
+
void polyvecm_ntt(polyvecm *x);
|
|
114
|
+
|
|
115
|
+
#define polyvecmk_expand_S HAETAE_NAMESPACE(polyvecmk_expand_S)
|
|
116
|
+
void polyvecmk_expand_S(polyvecm *u, polyveck *v,
|
|
117
|
+
const uint8_t seed[HAETAE_CRHBYTES], uint16_t nonce);
|
|
118
|
+
|
|
119
|
+
#define polyvecm_pointwise_acc_montgomery \
|
|
120
|
+
HAETAE_NAMESPACE(polyvecm_pointwise_acc_montgomery)
|
|
121
|
+
void polyvecm_pointwise_acc_montgomery(poly *w, const polyvecm *u,
|
|
122
|
+
const polyvecm *v);
|
|
123
|
+
|
|
124
|
+
#define polyvecmk_sk_singular_value \
|
|
125
|
+
HAETAE_NAMESPACE(polyvecmk_sk_singular_value)
|
|
126
|
+
int64_t polyvecmk_sk_singular_value(const polyvecm *s1, const polyveck *s2);
|
|
127
|
+
|
|
128
|
+
#define polyvecmk_sing_value HAETAE_NAMESPACE(polyvecmk_sing_value)
|
|
129
|
+
int64_t polyvecmk_sing_value(const polyvecm *s1, const polyveck *s2);
|
|
130
|
+
|
|
131
|
+
#endif /* !HAETAE_POLYVEC_H */
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#ifndef HAETAE_RANDOMBYTES_H
|
|
4
|
+
#define HAETAE_RANDOMBYTES_H
|
|
5
|
+
|
|
6
|
+
#include <stddef.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
#define RNG_SUCCESS 0
|
|
10
|
+
#define RNG_BAD_MAXLEN -1
|
|
11
|
+
#define RNG_BAD_OUTBUF -2
|
|
12
|
+
#define RNG_BAD_REQ_LEN -3
|
|
13
|
+
#define RNG_FAIL_SYSCALL -4
|
|
14
|
+
|
|
15
|
+
typedef struct {
|
|
16
|
+
unsigned char buffer[16];
|
|
17
|
+
int buffer_pos;
|
|
18
|
+
unsigned long length_remaining;
|
|
19
|
+
unsigned char key[32];
|
|
20
|
+
unsigned char ctr[16];
|
|
21
|
+
} AES_XOF_struct;
|
|
22
|
+
|
|
23
|
+
typedef struct {
|
|
24
|
+
unsigned char Key[32];
|
|
25
|
+
unsigned char V[16];
|
|
26
|
+
int reseed_counter;
|
|
27
|
+
int init;
|
|
28
|
+
} AES256_CTR_DRBG_struct;
|
|
29
|
+
|
|
30
|
+
void AES256_CTR_DRBG_Update(unsigned char *provided_data, unsigned char *Key,
|
|
31
|
+
unsigned char *V);
|
|
32
|
+
|
|
33
|
+
void randombytes_init(unsigned char *entropy_input,
|
|
34
|
+
unsigned char *personalization_string,
|
|
35
|
+
int security_strength);
|
|
36
|
+
|
|
37
|
+
int randombytes(uint8_t *out, size_t outlen);
|
|
38
|
+
|
|
39
|
+
#endif /* !HAETAE_RANDOMBYTES_H */
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
// Simple byte-aligned rANS encoder/decoder - public domain - Fabian 'ryg'
|
|
2
|
+
// Giesen 2014
|
|
3
|
+
//
|
|
4
|
+
// Not intended to be "industrial strength"; just meant to illustrate the
|
|
5
|
+
// general idea.
|
|
6
|
+
|
|
7
|
+
#ifndef RANS_BYTE_HEADER
|
|
8
|
+
#define RANS_BYTE_HEADER
|
|
9
|
+
|
|
10
|
+
#include <stdint.h>
|
|
11
|
+
|
|
12
|
+
#ifdef assert
|
|
13
|
+
#define RansAssert assert
|
|
14
|
+
#else
|
|
15
|
+
#define RansAssert(x)
|
|
16
|
+
#endif
|
|
17
|
+
|
|
18
|
+
// READ ME FIRST:
|
|
19
|
+
//
|
|
20
|
+
// This is designed like a typical arithmetic coder API, but there's three
|
|
21
|
+
// twists you absolutely should be aware of before you start hacking:
|
|
22
|
+
//
|
|
23
|
+
// 1. You need to encode data in *reverse* - last symbol first. rANS works
|
|
24
|
+
// like a stack: last in, first out.
|
|
25
|
+
// 2. Likewise, the encoder outputs bytes *in reverse* - that is, you give
|
|
26
|
+
// it a pointer to the *end* of your buffer (exclusive), and it will
|
|
27
|
+
// slowly move towards the beginning as more bytes are emitted.
|
|
28
|
+
// 3. Unlike basically any other entropy coder implementation you might
|
|
29
|
+
// have used, you can interleave data from multiple independent rANS
|
|
30
|
+
// encoders into the same bytestream without any extra signaling;
|
|
31
|
+
// you can also just write some bytes by yourself in the middle if
|
|
32
|
+
// you want to. This is in addition to the usual arithmetic encoder
|
|
33
|
+
// property of being able to switch models on the fly. Writing raw
|
|
34
|
+
// bytes can be useful when you have some data that you know is
|
|
35
|
+
// incompressible, and is cheaper than going through the rANS encode
|
|
36
|
+
// function. Using multiple rANS coders on the same byte stream wastes
|
|
37
|
+
// a few bytes compared to using just one, but execution of two
|
|
38
|
+
// independent encoders can happen in parallel on superscalar and
|
|
39
|
+
// Out-of-Order CPUs, so this can be *much* faster in tight decoding
|
|
40
|
+
// loops.
|
|
41
|
+
//
|
|
42
|
+
// This is why all the rANS functions take the write pointer as an
|
|
43
|
+
// argument instead of just storing it in some context struct.
|
|
44
|
+
|
|
45
|
+
// --------------------------------------------------------------------------
|
|
46
|
+
|
|
47
|
+
// L ('l' in the paper) is the lower bound of our normalization interval.
|
|
48
|
+
// Between this and our byte-aligned emission, we use 31 (not 32!) bits.
|
|
49
|
+
// This is done intentionally because exact reciprocals for 31-bit uints
|
|
50
|
+
// fit in 32-bit uints: this permits some optimizations during encoding.
|
|
51
|
+
#define RANS_BYTE_L (1u << 23) // lower bound of our normalization interval
|
|
52
|
+
|
|
53
|
+
// State for a rANS encoder. Yep, that's all there is to it.
|
|
54
|
+
typedef uint32_t RansState;
|
|
55
|
+
|
|
56
|
+
// Initialize a rANS encoder.
|
|
57
|
+
static inline void RansEncInit(RansState *r) { *r = RANS_BYTE_L; }
|
|
58
|
+
|
|
59
|
+
// Renormalize the encoder. Internal function.
|
|
60
|
+
static inline RansState RansEncRenorm(RansState x, uint8_t **pptr,
|
|
61
|
+
uint32_t freq, uint32_t scale_bits) {
|
|
62
|
+
uint32_t x_max =
|
|
63
|
+
((RANS_BYTE_L >> scale_bits) << 8) * freq; // this turns into a shift.
|
|
64
|
+
if (x >= x_max) {
|
|
65
|
+
uint8_t *ptr = *pptr;
|
|
66
|
+
do {
|
|
67
|
+
*--ptr = (uint8_t)(x & 0xff);
|
|
68
|
+
x >>= 8;
|
|
69
|
+
} while (x >= x_max);
|
|
70
|
+
*pptr = ptr;
|
|
71
|
+
}
|
|
72
|
+
return x;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Encodes a single symbol with range start "start" and frequency "freq".
|
|
76
|
+
// All frequencies are assumed to sum to "1 << scale_bits", and the
|
|
77
|
+
// resulting bytes get written to ptr (which is updated).
|
|
78
|
+
//
|
|
79
|
+
// NOTE: With rANS, you need to encode symbols in *reverse order*, i.e. from
|
|
80
|
+
// beginning to end! Likewise, the output bytestream is written *backwards*:
|
|
81
|
+
// ptr starts pointing at the end of the output buffer and keeps decrementing.
|
|
82
|
+
static inline void RansEncPut(RansState *r, uint8_t **pptr, uint32_t start,
|
|
83
|
+
uint32_t freq, uint32_t scale_bits) {
|
|
84
|
+
// renormalize
|
|
85
|
+
RansState x = RansEncRenorm(*r, pptr, freq, scale_bits);
|
|
86
|
+
|
|
87
|
+
// x = C(s,x)
|
|
88
|
+
*r = ((x / freq) << scale_bits) + (x % freq) + start;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Flushes the rANS encoder.
|
|
92
|
+
static inline void RansEncFlush(RansState *r, uint8_t **pptr) {
|
|
93
|
+
uint32_t x = *r;
|
|
94
|
+
uint8_t *ptr = *pptr;
|
|
95
|
+
|
|
96
|
+
ptr -= 4;
|
|
97
|
+
ptr[0] = (uint8_t)(x >> 0);
|
|
98
|
+
ptr[1] = (uint8_t)(x >> 8);
|
|
99
|
+
ptr[2] = (uint8_t)(x >> 16);
|
|
100
|
+
ptr[3] = (uint8_t)(x >> 24);
|
|
101
|
+
|
|
102
|
+
*pptr = ptr;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Initializes a rANS decoder.
|
|
106
|
+
// Unlike the encoder, the decoder works forwards as you'd expect.
|
|
107
|
+
static inline int RansDecInit(RansState *r, uint8_t **pptr) {
|
|
108
|
+
uint32_t x;
|
|
109
|
+
uint8_t *ptr = *pptr;
|
|
110
|
+
|
|
111
|
+
x = (uint32_t)ptr[0] << 0;
|
|
112
|
+
x |= (uint32_t)ptr[1] << 8;
|
|
113
|
+
x |= (uint32_t)ptr[2] << 16;
|
|
114
|
+
x |= (uint32_t)ptr[3] << 24;
|
|
115
|
+
if (x < RANS_BYTE_L || (RANS_BYTE_L << 8) <= x)
|
|
116
|
+
return 1; // initial state out of range
|
|
117
|
+
|
|
118
|
+
ptr += 4;
|
|
119
|
+
*pptr = ptr;
|
|
120
|
+
*r = x;
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Returns the current cumulative frequency (map it to a symbol yourself!)
|
|
125
|
+
static inline uint32_t RansDecGet(RansState *r, uint32_t scale_bits) {
|
|
126
|
+
return *r & ((1u << scale_bits) - 1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Advances in the bit stream by "popping" a single symbol with range start
|
|
130
|
+
// "start" and frequency "freq". All frequencies are assumed to sum to "1 <<
|
|
131
|
+
// scale_bits", and the resulting bytes get written to ptr (which is updated).
|
|
132
|
+
static inline void RansDecAdvance(RansState *r, uint8_t **pptr,
|
|
133
|
+
const uint8_t *end, uint32_t start,
|
|
134
|
+
uint32_t freq, uint32_t scale_bits) {
|
|
135
|
+
uint32_t mask = (1u << scale_bits) - 1;
|
|
136
|
+
|
|
137
|
+
// s, x = D(x)
|
|
138
|
+
uint32_t x = *r;
|
|
139
|
+
x = freq * (x >> scale_bits) + (x & mask) - start;
|
|
140
|
+
|
|
141
|
+
// renormalize
|
|
142
|
+
if (x < RANS_BYTE_L && *pptr < end) {
|
|
143
|
+
uint8_t *ptr = *pptr;
|
|
144
|
+
do
|
|
145
|
+
x = (x << 8) | *ptr++;
|
|
146
|
+
while (x < RANS_BYTE_L && ptr < end);
|
|
147
|
+
*pptr = ptr;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
*r = x;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// --------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
// That's all you need for a full encoder; below here are some utility
|
|
156
|
+
// functions with extra convenience or optimizations.
|
|
157
|
+
|
|
158
|
+
// Encoder symbol description
|
|
159
|
+
// This (admittedly odd) selection of parameters was chosen to make
|
|
160
|
+
// RansEncPutSymbol as cheap as possible.
|
|
161
|
+
typedef struct {
|
|
162
|
+
uint32_t x_max; // (Exclusive) upper bound of pre-normalization interval
|
|
163
|
+
uint32_t rcp_freq; // Fixed-point reciprocal frequency
|
|
164
|
+
uint32_t bias; // Bias
|
|
165
|
+
uint16_t cmpl_freq; // Complement of frequency: (1 << scale_bits) - freq
|
|
166
|
+
uint16_t rcp_shift; // Reciprocal shift
|
|
167
|
+
} RansEncSymbol;
|
|
168
|
+
|
|
169
|
+
// Decoder symbols are straightforward.
|
|
170
|
+
typedef struct {
|
|
171
|
+
uint16_t start; // Start of range.
|
|
172
|
+
uint16_t freq; // Symbol frequency.
|
|
173
|
+
} RansDecSymbol;
|
|
174
|
+
|
|
175
|
+
// Initializes an encoder symbol to start "start" and frequency "freq"
|
|
176
|
+
static inline void RansEncSymbolInit(RansEncSymbol *s, uint32_t start,
|
|
177
|
+
uint32_t freq, uint32_t scale_bits) {
|
|
178
|
+
RansAssert(scale_bits <= 16);
|
|
179
|
+
RansAssert(start <= (1u << scale_bits));
|
|
180
|
+
RansAssert(freq <= (1u << scale_bits) - start);
|
|
181
|
+
|
|
182
|
+
// Say M := 1 << scale_bits.
|
|
183
|
+
//
|
|
184
|
+
// The original encoder does:
|
|
185
|
+
// x_new = (x/freq)*M + start + (x%freq)
|
|
186
|
+
//
|
|
187
|
+
// The fast encoder does (schematically):
|
|
188
|
+
// q = mul_hi(x, rcp_freq) >> rcp_shift (division)
|
|
189
|
+
// r = x - q*freq (remainder)
|
|
190
|
+
// x_new = q*M + bias + r (new x)
|
|
191
|
+
// plugging in r into x_new yields:
|
|
192
|
+
// x_new = bias + x + q*(M - freq)
|
|
193
|
+
// =: bias + x + q*cmpl_freq (*)
|
|
194
|
+
//
|
|
195
|
+
// and we can just precompute cmpl_freq. Now we just need to
|
|
196
|
+
// set up our parameters such that the original encoder and
|
|
197
|
+
// the fast encoder agree.
|
|
198
|
+
|
|
199
|
+
s->x_max = ((RANS_BYTE_L >> scale_bits) << 8) * freq;
|
|
200
|
+
s->cmpl_freq = (uint16_t)((1 << scale_bits) - freq);
|
|
201
|
+
if (freq < 2) {
|
|
202
|
+
// freq=0 symbols are never valid to encode, so it doesn't matter what
|
|
203
|
+
// we set our values to.
|
|
204
|
+
//
|
|
205
|
+
// freq=1 is tricky, since the reciprocal of 1 is 1; unfortunately,
|
|
206
|
+
// our fixed-point reciprocal approximation can only multiply by values
|
|
207
|
+
// smaller than 1.
|
|
208
|
+
//
|
|
209
|
+
// So we use the "next best thing": rcp_freq=0xffffffff, rcp_shift=0.
|
|
210
|
+
// This gives:
|
|
211
|
+
// q = mul_hi(x, rcp_freq) >> rcp_shift
|
|
212
|
+
// = mul_hi(x, (1<<32) - 1)) >> 0
|
|
213
|
+
// = floor(x - x/(2^32))
|
|
214
|
+
// = x - 1 if 1 <= x < 2^32
|
|
215
|
+
// and we know that x>0 (x=0 is never in a valid normalization interval).
|
|
216
|
+
//
|
|
217
|
+
// So we now need to choose the other parameters such that
|
|
218
|
+
// x_new = x*M + start
|
|
219
|
+
// plug it in:
|
|
220
|
+
// x*M + start (desired result)
|
|
221
|
+
// = bias + x + q*cmpl_freq (*)
|
|
222
|
+
// = bias + x + (x - 1)*(M - 1) (plug in q=x-1, cmpl_freq)
|
|
223
|
+
// = bias + 1 + (x - 1)*M
|
|
224
|
+
// = x*M + (bias + 1 - M)
|
|
225
|
+
//
|
|
226
|
+
// so we have start = bias + 1 - M, or equivalently
|
|
227
|
+
// bias = start + M - 1.
|
|
228
|
+
s->rcp_freq = ~0u;
|
|
229
|
+
s->rcp_shift = 0;
|
|
230
|
+
s->bias = start + (1 << scale_bits) - 1;
|
|
231
|
+
} else {
|
|
232
|
+
// Alverson, "Integer Division using reciprocals"
|
|
233
|
+
// shift=ceil(log2(freq))
|
|
234
|
+
uint32_t shift = 0;
|
|
235
|
+
while (freq > (1u << shift))
|
|
236
|
+
shift++;
|
|
237
|
+
|
|
238
|
+
s->rcp_freq = (uint32_t)(((1ull << (shift + 31)) + freq - 1) / freq);
|
|
239
|
+
s->rcp_shift = shift - 1;
|
|
240
|
+
|
|
241
|
+
// With these values, 'q' is the correct quotient, so we
|
|
242
|
+
// have bias=start.
|
|
243
|
+
s->bias = start;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Initialize a decoder symbol to start "start" and frequency "freq"
|
|
248
|
+
static inline void RansDecSymbolInit(RansDecSymbol *s, uint32_t start,
|
|
249
|
+
uint32_t freq) {
|
|
250
|
+
RansAssert(start <= (1 << 16));
|
|
251
|
+
RansAssert(freq <= (1 << 16) - start);
|
|
252
|
+
s->start = (uint16_t)start;
|
|
253
|
+
s->freq = (uint16_t)freq;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Encodes a given symbol. This is faster than straight RansEnc since we can do
|
|
257
|
+
// multiplications instead of a divide.
|
|
258
|
+
//
|
|
259
|
+
// See RansEncSymbolInit for a description of how this works.
|
|
260
|
+
static inline void RansEncPutSymbol(RansState *r, uint8_t **pptr,
|
|
261
|
+
RansEncSymbol const *sym) {
|
|
262
|
+
RansAssert(sym->x_max != 0); // can't encode symbol with freq=0
|
|
263
|
+
|
|
264
|
+
// renormalize
|
|
265
|
+
uint32_t x = *r;
|
|
266
|
+
uint32_t x_max = sym->x_max;
|
|
267
|
+
if (x >= x_max) {
|
|
268
|
+
uint8_t *ptr = *pptr;
|
|
269
|
+
do {
|
|
270
|
+
*--ptr = (uint8_t)(x & 0xff);
|
|
271
|
+
x >>= 8;
|
|
272
|
+
} while (x >= x_max);
|
|
273
|
+
*pptr = ptr;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// x = C(s,x)
|
|
277
|
+
// NOTE: written this way so we get a 32-bit "multiply high" when
|
|
278
|
+
// available. If you're on a 64-bit platform with cheap multiplies
|
|
279
|
+
// (e.g. x64), just bake the +32 into rcp_shift.
|
|
280
|
+
uint32_t q =
|
|
281
|
+
(uint32_t)(((uint64_t)x * sym->rcp_freq) >> 32) >> sym->rcp_shift;
|
|
282
|
+
*r = x + sym->bias + q * sym->cmpl_freq;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Equivalent to RansDecAdvance that takes a symbol.
|
|
286
|
+
static inline void RansDecAdvanceSymbol(RansState *r, uint8_t **pptr,
|
|
287
|
+
const uint8_t *end,
|
|
288
|
+
RansDecSymbol const *sym,
|
|
289
|
+
uint32_t scale_bits) {
|
|
290
|
+
RansDecAdvance(r, pptr, end, sym->start, sym->freq, scale_bits);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Advances in the bit stream by "popping" a single symbol with range start
|
|
294
|
+
// "start" and frequency "freq". All frequencies are assumed to sum to "1 <<
|
|
295
|
+
// scale_bits". No renormalization or output happens.
|
|
296
|
+
static inline void RansDecAdvanceStep(RansState *r, uint32_t start,
|
|
297
|
+
uint32_t freq, uint32_t scale_bits) {
|
|
298
|
+
uint32_t mask = (1u << scale_bits) - 1;
|
|
299
|
+
|
|
300
|
+
// s, x = D(x)
|
|
301
|
+
uint32_t x = *r;
|
|
302
|
+
*r = freq * (x >> scale_bits) + (x & mask) - start;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Equivalent to RansDecAdvanceStep that takes a symbol.
|
|
306
|
+
static inline void RansDecAdvanceSymbolStep(RansState *r,
|
|
307
|
+
RansDecSymbol const *sym,
|
|
308
|
+
uint32_t scale_bits) {
|
|
309
|
+
RansDecAdvanceStep(r, sym->start, sym->freq, scale_bits);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Renormalize.
|
|
313
|
+
static inline void RansDecRenorm(RansState *r, uint8_t **pptr) {
|
|
314
|
+
// renormalize
|
|
315
|
+
uint32_t x = *r;
|
|
316
|
+
if (x < RANS_BYTE_L) {
|
|
317
|
+
uint8_t *ptr = *pptr;
|
|
318
|
+
do
|
|
319
|
+
x = (x << 8) | *ptr++;
|
|
320
|
+
while (x < RANS_BYTE_L);
|
|
321
|
+
*pptr = ptr;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
*r = x;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Verify final state
|
|
328
|
+
static inline int RansDecVerify(const RansState *const r) {
|
|
329
|
+
if (*r != RANS_BYTE_L) {
|
|
330
|
+
return 1; // the final state is inconsistent with the initial state
|
|
331
|
+
}
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
#endif // RANS_BYTE_HEADER
|