Skip to content

Commit 4e75301

Browse files
authored
Moved everything to SHA256 (#17)
* Moved everything to SHA256 * Updated Docs and comments * Formatted
1 parent 11e875a commit 4e75301

6 files changed

Lines changed: 45 additions & 52 deletions

File tree

‎client/src/main.rs‎

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use common::{
1111
read_object_into_headers_sync, Hash, Header, Mode, ObjectType, BLOB_KEY, INDEX_KEY, TREE_KEY,
1212
};
1313
use rayon::prelude::*;
14-
use sha2::{Digest, Sha512};
14+
use sha2::{Digest, Sha256};
1515
use std::{
1616
collections::HashMap,
1717
fs::{create_dir, create_dir_all, read_dir, File},
@@ -202,7 +202,7 @@ impl<'a> CacheObject<'a> {
202202

203203
let mode = Mode::from_str(mode).expect("valid mode");
204204

205-
let mut hash: [u8; 64] = [0; 64];
205+
let mut hash: [u8; 32] = [0; 32];
206206
file.read_exact(&mut hash).expect("file to contain hash");
207207

208208
let hash = Hash::from(hash);
@@ -306,7 +306,7 @@ impl Object for Index {
306306

307307
fn get_hash(&self) -> Hash {
308308
let body = self.get_body();
309-
let mut hasher = Sha512::new();
309+
let mut hasher = Sha256::new();
310310
write!(hasher, "{}{}", self.get_prefix(), body).unwrap();
311311
Hash::from(hasher)
312312
}
@@ -425,7 +425,7 @@ impl Object for Tree {
425425

426426
fn get_hash(&self) -> Hash {
427427
let body = self.get_body();
428-
let mut hasher = Sha512::new();
428+
let mut hasher = Sha256::new();
429429
write!(hasher, "{}", self.get_prefix()).unwrap();
430430
hasher
431431
.write_all(&body)
@@ -487,7 +487,7 @@ impl Blob {
487487
let size = src.metadata().unwrap().len();
488488
let prefix = format!("{} {}\0", BLOB_KEY, size);
489489

490-
let mut hasher = Sha512::new();
490+
let mut hasher = Sha256::new();
491491
hasher.write_all(prefix.as_bytes()).unwrap();
492492

493493
let f = File::open(src).unwrap();
@@ -543,7 +543,7 @@ impl Object for Blob {
543543
}
544544

545545
fn get_hash(&self) -> Hash {
546-
let mut hasher = Sha512::new();
546+
let mut hasher = Sha256::new();
547547
hasher.write_all(self.get_prefix().as_bytes()).unwrap();
548548

549549
let f = File::open(&self.file).unwrap();
@@ -1034,7 +1034,7 @@ fn unpack_archive(cache: &Path, path: &Path) -> anyhow::Result<()> {
10341034
let index_data = archive.index.to_data();
10351035
let index_header = Header::new(ObjectType::Index, index_data.len() as u64);
10361036

1037-
let mut hasher = Sha512::new();
1037+
let mut hasher = Sha256::new();
10381038
hasher.write_all(index_header.to_string().as_bytes())?;
10391039
hasher.write_all(&index_data)?;
10401040
assert!(Hash::from(hasher) == archive.hash);
@@ -1377,21 +1377,18 @@ mod tests {
13771377
let mut reader = BufReader::new(f);
13781378
let archive = Archive::<RawEntryData>::from_data(&mut reader).expect("archive to parse");
13791379

1380-
// Archive hash must match the SHA-512 of the index header + body bytes —
1381-
// the same integrity invariant `unpack_archive` enforces when restoring
1382-
// into a store. This catches mismatches between archive.hash and
1383-
// archive.index without needing a separate reference build.
1380+
// Archive hash must match the SHA-256 of the index header + body bytes
13841381
let index_data = archive.index.to_data();
13851382
let index_header = Header::new(ObjectType::Index, index_data.len() as u64);
1386-
let mut hasher = Sha512::new();
1383+
let mut hasher = Sha256::new();
13871384
hasher
13881385
.write_all(index_header.to_string().as_bytes())
13891386
.unwrap();
13901387
hasher.write_all(&index_data).unwrap();
13911388
assert_eq!(
13921389
archive.hash,
13931390
Hash::from(hasher),
1394-
"archive hash must equal sha512(index header + body)"
1391+
"archive hash must equal Sha256(index header + body)"
13951392
);
13961393

13971394
// Body has 1 tree + 3 blobs = 4 entries (index is in the archive header, not body).

‎common/src/archive.rs‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use anyhow::anyhow;
1111
use futures::AsyncReadExt;
1212
use lzma_rust2::LzmaOptions;
1313
use serde::{Deserialize, Serialize};
14-
use sha2::{Digest, Sha512};
14+
use sha2::{Digest, Sha256};
1515

1616
use crate::{
1717
object_body::{Index, Object},
@@ -229,7 +229,7 @@ where
229229
.try_into()
230230
.map_err(|_| anyhow!("Invalid Compression"))?;
231231

232-
let mut hash: [u8; 64] = [0; 64];
232+
let mut hash: [u8; 32] = [0; 32];
233233
reader.read_exact(&mut hash)?;
234234
let hash: Hash = hash.into();
235235

@@ -444,7 +444,7 @@ where
444444
break;
445445
}
446446

447-
let mut hash: [u8; 64] = [0; 64];
447+
let mut hash: [u8; 32] = [0; 32];
448448
reader.read_exact(&mut hash)?;
449449
let hash: Hash = hash.into();
450450

@@ -476,7 +476,7 @@ where
476476
let mut data: Vec<u8> = vec![0; amount as usize];
477477
reader.read_exact(&mut data[..])?;
478478

479-
let mut hasher = Sha512::new();
479+
let mut hasher = Sha256::new();
480480
hasher.write_all(&data)?;
481481
assert!(Hash::from(hasher) == entry.hash);
482482

@@ -499,7 +499,7 @@ mod tests {
499499
use std::collections::HashMap;
500500

501501
fn empty_archive(compression: CompressionAlgorithm) -> Archive<RawEntryData> {
502-
let zero = Hash::from([0u8; 64]);
502+
let zero = Hash::from([0u8; 32]);
503503
Archive {
504504
header: HEADER,
505505
compression,

‎common/src/hash.rs‎

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ use serde::de::{self, Visitor};
33
use serde::{Deserialize, Deserializer, Serialize};
44
use sha2::digest::FixedOutput;
55

6-
use sha2::Sha512;
6+
use sha2::Sha256;
77
use std::fmt::{self, Debug, Display};
88
use std::path::{Path, PathBuf};
99
use std::str::FromStr;
1010
// use std::hash::Hash;
1111

1212
#[derive(Clone, Serialize)]
1313
pub struct Hash {
14-
// Sha512 Hash value
14+
// Sha256 Hash value
1515
#[serde(skip)]
16-
pub hash: [u8; 64],
16+
pub hash: [u8; 32],
1717
hash_string: String,
1818
}
1919

@@ -27,13 +27,13 @@ impl Hash {
2727
}
2828

2929
pub fn from_string(value: &str) -> Option<Self> {
30-
if value.len() != 128 {
30+
if value.len() != 64 {
3131
return None;
3232
}
3333

3434
let hash = hex::decode(value).ok()?;
3535

36-
if hash.len() != 64 {
36+
if hash.len() != 32 {
3737
return None;
3838
}
3939

@@ -56,7 +56,7 @@ impl Hash {
5656
return None;
5757
}
5858

59-
if filename.len() != 126 {
59+
if filename.len() != 62 {
6060
return None;
6161
}
6262

@@ -90,13 +90,11 @@ impl TryFrom<String> for Hash {
9090
type Error = anyhow::Error;
9191

9292
fn try_from(value: String) -> Result<Self, Self::Error> {
93-
if value.len() != 128 {
94-
return Err(anyhow!(
95-
"Invalid length. Hash has to be 128 characters long"
96-
));
93+
if value.len() != 64 {
94+
return Err(anyhow!("Invalid length. Hash has to be 64 characters long"));
9795
}
9896

99-
let mut hash = [0u8; 64];
97+
let mut hash = [0u8; 32];
10098
hex::decode_to_slice(&value, &mut hash)?;
10199

102100
Ok(Self {
@@ -110,13 +108,11 @@ impl TryFrom<&str> for Hash {
110108
type Error = anyhow::Error;
111109

112110
fn try_from(value: &str) -> Result<Self, Self::Error> {
113-
if value.len() != 128 {
114-
return Err(anyhow!(
115-
"Invalid length. Hash has to be 128 characters long"
116-
));
111+
if value.len() != 64 {
112+
return Err(anyhow!("Invalid length. Hash has to be 64 characters long"));
117113
}
118114

119-
let mut hash = [0u8; 64];
115+
let mut hash = [0u8; 32];
120116
hex::decode_to_slice(value, &mut hash)?;
121117

122118
Ok(Self {
@@ -130,30 +126,30 @@ impl TryFrom<&[u8]> for Hash {
130126
type Error = anyhow::Error;
131127

132128
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
133-
if value.len() != 64 {
134-
return Err(anyhow!("Invalid length. Slice must be 64 bytes long"));
129+
if value.len() != 32 {
130+
return Err(anyhow!("Invalid length. Slice must be 32 bytes long"));
135131
}
136132

137-
let data: [u8; 64] = value.try_into()?;
133+
let data: [u8; 32] = value.try_into()?;
138134
Ok(Self {
139135
hash_string: hex::encode(value),
140136
hash: data,
141137
})
142138
}
143139
}
144140

145-
impl From<[u8; 64]> for Hash {
146-
fn from(value: [u8; 64]) -> Self {
141+
impl From<[u8; 32]> for Hash {
142+
fn from(value: [u8; 32]) -> Self {
147143
Self {
148144
hash_string: hex::encode(value),
149145
hash: value,
150146
}
151147
}
152148
}
153149

154-
impl From<Sha512> for Hash {
155-
fn from(value: Sha512) -> Self {
156-
Self::from(Into::<[u8; 64]>::into(value.finalize_fixed()))
150+
impl From<Sha256> for Hash {
151+
fn from(value: Sha256) -> Self {
152+
Self::from(Into::<[u8; 32]>::into(value.finalize_fixed()))
157153
}
158154
}
159155

@@ -180,17 +176,17 @@ impl<'de> Deserialize<'de> for Hash {
180176
type Value = Hash;
181177

182178
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
183-
formatter.write_str("Sha512 hex string Hash")
179+
formatter.write_str("Sha256 hex string Hash")
184180
}
185181

186182
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
187183
where
188184
E: serde::de::Error,
189185
{
190-
if value.len() != 128 {
186+
if value.len() != 64 {
191187
return Err(de::Error::invalid_length(
192188
value.len(),
193-
&"A hex string with 128 characters",
189+
&"A hex string with 64 characters",
194190
));
195191
}
196192

@@ -201,10 +197,10 @@ impl<'de> Deserialize<'de> for Hash {
201197
where
202198
E: serde::de::Error,
203199
{
204-
if value.len() != 128 {
200+
if value.len() != 64 {
205201
return Err(de::Error::invalid_length(
206202
value.len(),
207-
&"A hex string with 128 characters",
203+
&"A hex string with 64 characters",
208204
));
209205
}
210206

‎common/src/object.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{Hash, Header};
22
use anyhow::{anyhow, Result};
3-
use sha2::{Digest, Sha512};
3+
use sha2::{Digest, Sha256};
44
use std::io::{BufReader, Read, Write};
55

66
pub struct Object {
@@ -10,7 +10,7 @@ pub struct Object {
1010

1111
impl Object {
1212
pub fn to_hash(&self) -> Hash {
13-
let mut hasher = Sha512::new();
13+
let mut hasher = Sha256::new();
1414
hasher
1515
.write_all(self.header.to_string().as_bytes())
1616
.expect("Out of Memory");

‎docs/designs/design.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Design
22

3-
The ArtifactRepository design is based on a SHA2-512 Merkel Tree which serves as the foundation of the Artifact. Each file within an Artifact is content addressed by its sha512 hash and directories are stored in an identical format to git. In general the object structure closely matches that of git.
3+
The ArtifactRepository design is based on a SHA2-256 Merkel Tree which serves as the foundation of the Artifact. Each file within an Artifact is content addressed by its sha256 hash and directories are stored in an identical format to git. In general the object structure closely matches that of git.
44

55
The very top level of an Artifact is called an **Index** (git calls it a commit). This defines the artifact and contains any and all relevant metadata, such as the timestamp of creation. But since it simply contains any and all metadata in a simple key value format similar to HTTP headers, it allows for the same level of flexibility and metadata to be attached to an index.
66
Some possibilities could include:
@@ -45,7 +45,7 @@ It is structured as follows:
4545
| [u8; 4] | header / magic number |
4646
| [u8; 1] | version |
4747
| [u8; 2] | compression method |
48-
| [u8; 64] | SHA2 512 index hash |
48+
| [u8; 32] | SHA2 256 index hash |
4949
| [u8; N] | index data |
5050
| [u8; 1] | null byte |
5151
| [u8; N] | data (compressed with above method) |

‎server/src/main.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl From<std::io::Error> for ErrorResult {
144144

145145
// let file = File::create(path).await?;
146146
// let mut writer = BufWriter::new(file).compat_write();
147-
// let mut hasher = Sha512::new();
147+
// let mut hasher = Sha256::new();
148148

149149
// header.write_to(&mut hasher)?;
150150
// header.write_to_async(&mut writer).await?;

0 commit comments

Comments
 (0)