mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-03 22:28:46 +00:00
big: Add internal_int_kronecker.
This commit is contained in:
@@ -79,135 +79,6 @@ print :: proc(name: string, a: ^Int, base := i8(10), print_name := true, newline
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int_to_byte :: proc(v: ^Int) {
|
|
||||||
err: Error;
|
|
||||||
size: int;
|
|
||||||
print("v: ", v);
|
|
||||||
fmt.println();
|
|
||||||
|
|
||||||
t := &Int{};
|
|
||||||
defer destroy(t);
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b1 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_big(v, b1);
|
|
||||||
int_from_bytes_big(t, b1);
|
|
||||||
fmt.printf("big: %v | err: %v\n", b1, err);
|
|
||||||
|
|
||||||
int_from_bytes_big(t, b1);
|
|
||||||
if internal_cmp_mag(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b2 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_big_python(v, b2);
|
|
||||||
fmt.printf("big python: %v | err: %v\n", b2, err);
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
int_from_bytes_big_python(t, b2);
|
|
||||||
if internal_cmp_mag(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v, true); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b3 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_big(v, b3, true);
|
|
||||||
fmt.printf("big signed: %v | err: %v\n", b3, err);
|
|
||||||
|
|
||||||
int_from_bytes_big(t, b3, true);
|
|
||||||
if internal_cmp(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v, true); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b4 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_big_python(v, b4, true);
|
|
||||||
fmt.printf("big signed python: %v | err: %v\n", b4, err);
|
|
||||||
|
|
||||||
int_from_bytes_big_python(t, b4, true);
|
|
||||||
if internal_cmp(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int_to_byte_little :: proc(v: ^Int) {
|
|
||||||
err: Error;
|
|
||||||
size: int;
|
|
||||||
print("v: ", v);
|
|
||||||
fmt.println();
|
|
||||||
|
|
||||||
t := &Int{};
|
|
||||||
defer destroy(t);
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b1 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_little(v, b1);
|
|
||||||
fmt.printf("little: %v | err: %v\n", b1, err);
|
|
||||||
|
|
||||||
int_from_bytes_little(t, b1);
|
|
||||||
if internal_cmp_mag(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b2 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_little_python(v, b2);
|
|
||||||
fmt.printf("little python: %v | err: %v\n", b2, err);
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
int_from_bytes_little_python(t, b2);
|
|
||||||
if internal_cmp_mag(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v, true); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b3 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_little(v, b3, true);
|
|
||||||
fmt.printf("little signed: %v | err: %v\n", b3, err);
|
|
||||||
|
|
||||||
int_from_bytes_little(t, b3, true);
|
|
||||||
if internal_cmp(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if size, err = int_to_bytes_size(v, true); err != nil {
|
|
||||||
fmt.printf("int_to_bytes_size returned: %v\n", err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
b4 := make([]u8, size, context.temp_allocator);
|
|
||||||
err = int_to_bytes_little_python(v, b4, true);
|
|
||||||
fmt.printf("little signed python: %v | err: %v\n", b4, err);
|
|
||||||
|
|
||||||
int_from_bytes_little_python(t, b4, true);
|
|
||||||
if internal_cmp(t, v) != 0 {
|
|
||||||
print("\tError parsing t: ", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// printf :: fmt.printf;
|
// printf :: fmt.printf;
|
||||||
|
|
||||||
demo :: proc() {
|
demo :: proc() {
|
||||||
|
|||||||
@@ -109,6 +109,101 @@ internal_int_exponent_mod :: proc(res, G, X, P: ^Int, allocator := context.alloc
|
|||||||
return _private_int_exponent_mod(res, G, X, P, 0);
|
return _private_int_exponent_mod(res, G, X, P, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Kronecker symbol (a|p)
|
||||||
|
Straightforward implementation of algorithm 1.4.10 in
|
||||||
|
Henri Cohen: "A Course in Computational Algebraic Number Theory"
|
||||||
|
|
||||||
|
@book{cohen2013course,
|
||||||
|
title={A course in computational algebraic number theory},
|
||||||
|
author={Cohen, Henri},
|
||||||
|
volume={138},
|
||||||
|
year={2013},
|
||||||
|
publisher={Springer Science \& Business Media}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assumes `a` and `p` to not be `nil` and to have been initialized.
|
||||||
|
*/
|
||||||
|
internal_int_kronecker :: proc(a, p: ^Int, allocator := context.allocator) -> (kronecker: int, err: Error) {
|
||||||
|
context.allocator = allocator;
|
||||||
|
|
||||||
|
a1, p1, r := &Int{}, &Int{}, &Int{};
|
||||||
|
defer internal_destroy(a1, p1, r);
|
||||||
|
|
||||||
|
table := []int{0, 1, 0, -1, 0, -1, 0, 1};
|
||||||
|
|
||||||
|
if internal_int_is_zero(p) {
|
||||||
|
if a.used == 1 && a.digit[0] == 1 {
|
||||||
|
return 1, nil;
|
||||||
|
} else {
|
||||||
|
return 0, nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if internal_is_even(a) && internal_is_even(p) {
|
||||||
|
return 0, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_copy(a1, a) or_return;
|
||||||
|
internal_copy(p1, p) or_return;
|
||||||
|
|
||||||
|
v := internal_count_lsb(p1) or_return;
|
||||||
|
internal_shr(p1, p1, v) or_return;
|
||||||
|
|
||||||
|
k := 1 if v & 1 == 0 else table[a.digit[0] & 7];
|
||||||
|
|
||||||
|
if internal_is_negative(p1) {
|
||||||
|
p1.sign = .Zero_or_Positive;
|
||||||
|
if internal_is_negative(a1) {
|
||||||
|
k = -k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_zero(r) or_return;
|
||||||
|
|
||||||
|
for {
|
||||||
|
if internal_is_zero(a1) {
|
||||||
|
if internal_cmp(p1, 1) == 0 {
|
||||||
|
return k, nil;
|
||||||
|
} else {
|
||||||
|
return 0, nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v = internal_count_lsb(a1) or_return;
|
||||||
|
internal_shr(a1, a1, v) or_return;
|
||||||
|
|
||||||
|
if v & 1 == 1 {
|
||||||
|
k = k * table[p1.digit[0] & 7];
|
||||||
|
}
|
||||||
|
|
||||||
|
if internal_is_negative(a1) {
|
||||||
|
/*
|
||||||
|
Compute k = (-1)^((a1)*(p1-1)/4) * k.
|
||||||
|
a1.digit[0] + 1 cannot overflow because the MSB
|
||||||
|
of the DIGIT type is not set by definition.
|
||||||
|
*/
|
||||||
|
if a1.digit[0] + 1 & p1.digit[0] & 2 != 0 {
|
||||||
|
k = -k;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
Compute k = (-1)^((a1-1)*(p1-1)/4) * k.
|
||||||
|
*/
|
||||||
|
if a1.digit[0] & p1.digit[0] & 2 != 0 {
|
||||||
|
k = -k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal_copy(r, a1) or_return;
|
||||||
|
r.sign = .Zero_or_Positive;
|
||||||
|
|
||||||
|
internal_mod(a1, p1, r) or_return;
|
||||||
|
internal_copy(p1, r) or_return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns the number of Rabin-Miller trials needed for a given bit size.
|
Returns the number of Rabin-Miller trials needed for a given bit size.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user