Strip xseg stuff
[archipelago] / xseg / hash.c
1 /*
2  * Copyright 2013 GRNET S.A. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or
5  * without modification, are permitted provided that the following
6  * conditions are met:
7  *
8  *   1. Redistributions of source code must retain the above
9  *      copyright notice, this list of conditions and the following
10  *      disclaimer.
11  *   2. Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials
14  *      provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * The views and conclusions contained in the software and
30  * documentation are those of the authors and should not be
31  * interpreted as representing official policies, either expressed
32  * or implied, of GRNET S.A.
33  */
34
35 #include <hash.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 static char get_hex(unsigned int h)
41 {
42         switch (h)
43         {
44                 case 0:
45                 case 1:
46                 case 2:
47                 case 3:
48                 case 4:
49                 case 5:
50                 case 6:
51                 case 7:
52                 case 8:
53                 case 9:
54                         return h + '0';
55                 case 10:
56                         return 'a';
57                 case 11:
58                         return 'b';
59                 case 12:
60                         return 'c';
61                 case 13:
62                         return 'd';
63                 case 14:
64                         return 'e';
65                 case 15:
66                         return 'f';
67         }
68         /* not reachable */
69         return '0';
70 }
71
72 /* hexlify function.
73  * Unsafe. Doesn't check if data length is odd!
74  */
75
76 void hexlify(unsigned char *data, long datalen, char *hex)
77 {
78         long i;
79         for (i=0; i<datalen; i++){
80                 hex[2*i] = get_hex((data[i] & 0xF0) >> 4);
81                 hex[2*i + 1] = get_hex(data[i] & 0x0F);
82         }
83 }
84
85 void unhexlify(char *hex, unsigned char *data)
86 {
87         int i;
88         char c;
89         for (i=0; i<SHA256_DIGEST_LENGTH; i++){
90                 data[i] = 0;
91                 c = hex[2*i];
92                 if (isxdigit(c)){
93                         if (isdigit(c)){
94                                 c-= '0';
95                         }
96                         else {
97                                 c = tolower(c);
98                                 c = c-'a' + 10;
99                         }
100                 }
101                 else {
102                         c = 0;
103                 }
104                 data[i] |= (c << 4) & 0xF0;
105                 c = hex[2*i+1];
106                 if (isxdigit(c)){
107                         if (isdigit(c)){
108                                 c-= '0';
109                         }
110                         else {
111                                 c = tolower(c);
112                                 c = c-'a' + 10;
113                         }
114                 }
115                 else {
116                         c = 0;
117                 }
118                 data[i] |= c & 0x0F;
119         }
120 }
121
122 void merkle_hash(unsigned char *hashes, unsigned long len,
123                 unsigned char hash[SHA256_DIGEST_SIZE])
124 {
125         unsigned long i, l, s = 2;
126         unsigned long nr = len/SHA256_DIGEST_SIZE;
127         unsigned char *buf;
128         unsigned char tmp_hash[SHA256_DIGEST_SIZE];
129
130         if (!nr){
131                 SHA256(hashes, 0, hash);
132                 return;
133         }
134         if (nr == 1){
135                 memcpy(hash, hashes, SHA256_DIGEST_SIZE);
136                 return;
137         }
138         while (s < nr)
139                 s = s << 1;
140         buf = malloc(sizeof(unsigned char)* SHA256_DIGEST_SIZE * s);
141         memcpy(buf, hashes, nr * SHA256_DIGEST_SIZE);
142         memset(buf + nr * SHA256_DIGEST_SIZE, 0, (s - nr) * SHA256_DIGEST_SIZE);
143         for (l = s; l > 1; l = l/2) {
144                 for (i = 0; i < l; i += 2) {
145                         SHA256(buf + (i * SHA256_DIGEST_SIZE),
146                                         2 * SHA256_DIGEST_SIZE, tmp_hash);
147                         memcpy(buf + (i/2 * SHA256_DIGEST_SIZE),
148                                         tmp_hash, SHA256_DIGEST_SIZE);
149                 }
150         }
151         memcpy(hash, buf, SHA256_DIGEST_SIZE);
152 }
153