aboutsummaryrefslogtreecommitdiff
path: root/src/gen/seed.c
blob: 5b26718fa3a15bf11687c038f22d14b6ca45622e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 * ecgen, tool for generating Elliptic curve domain parameters
 * Copyright (C) 2017 J08nY
 */

#include "seed.h"
#include "io/output.h"
#include "util/memory.h"

seed_t *seed_new(void) { return try_calloc(sizeof(seed_t)); }

seed_t *seed_copy(const seed_t *src, seed_t *dest) {
	if (src->seed) dest->seed = gcopy(src->seed);
	return dest;
}

seed_t *seed_new_copy(const seed_t *src) {
	seed_t *result = seed_new();
	return seed_copy(src, result);
}

seed_t *seed_clone(const seed_t *src, seed_t *dest) {
	if (src->seed) dest->seed = gclone(src->seed);
	return dest;
}

seed_t *seed_new_clone(const seed_t *src) {
	seed_t *result = seed_new();
	return seed_clone(src, result);
}

void seed_free(seed_t **seed) {
	if (*seed) {
		if ((*seed)->seed && isclone((*seed)->seed)) {
			gunclone((*seed)->seed);
		}
		try_free(*seed);
		*seed = NULL;
	}
}

static GEN seed_stoi(const char *cstr) {
	pari_sp ltop = avma;

	size_t len = strlen(cstr);
	char *seed_str;
	if (len <= 3 || !(cstr[0] == '0' && (cstr[1] == 'x' || cstr[1] == 'X'))) {
		seed_str = try_malloc((size_t)(len + 3));
		strncpy(seed_str + 2, cstr, len);
		seed_str[0] = '0';
		seed_str[1] = 'x';
		seed_str[len + 2] = 0;
	} else {
		seed_str = try_malloc(len + 1);
		strncpy(seed_str, cstr, len);
	}
	GEN i = strtoi(seed_str);

	try_free(seed_str);
	return gerepilecopy(ltop, i);
}

static char *seed_itos(GEN seed) {
	pari_sp ltop = avma;
	char *result = pari_sprintf("%Px", seed);

	size_t seed_len = strlen(result);
	char *seed_str = try_malloc(seed_len + 1);
	strcpy(seed_str, result);

	avma = ltop;
	return seed_str;
}

static char *seed_strip(const char *cstr) {
	size_t seed_len = strlen(cstr);
	char *seed_str = try_malloc(seed_len + 1);
	char *prefix = strstr(cstr, "0x");
	if (prefix != NULL) {
		strcpy(seed_str, cstr + 2);
	} else {
		strcpy(seed_str, cstr);
	}
	return seed_str;
}

GENERATOR(seed_gen_random) {
	curve->seed = seed_new();
	curve->seed->seed = random_int(160);
	curve->seed->raw = seed_itos(curve->seed->seed);
	curve->seed->raw_len = strlen(curve->seed->raw);
	return 1;
}

GENERATOR(seed_gen_argument) {
	curve->seed = seed_new();
	curve->seed->seed = seed_stoi(cfg->seed);
	curve->seed->raw = seed_strip(cfg->seed);
	curve->seed->raw_len = strlen(curve->seed->raw);
	return 1;
}

GENERATOR(seed_gen_input) {
	pari_sp ltop = avma;

	GEN str = input_string("seed:");
	const char *cstr = GSTR(str);
	if (strlen(cstr) < 20) {
		fprintf(err, "SEED must be at least 160 bits(20 hex characters).\n");
		avma = ltop;
		return 0;
	}

	curve->seed = seed_new();
	curve->seed->seed = seed_stoi(cstr);
	curve->seed->raw = seed_strip(cstr);
	curve->seed->raw_len = strlen(curve->seed->raw);
	return 1;
}