chromium/third_party/shell-encryption/src/prng/chacha_prng.cc

/*
 * Copyright 2019 Google LLC.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "prng/chacha_prng.h"

#include <vector>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "prng/chacha_prng_util.h"
#include "status_macros.h"

namespace rlwe {

ChaChaPrng::ChaChaPrng(absl::string_view in_key, int position_in_buffer,
                       int salt_counter, std::vector<Uint8> buffer)
    : key_(in_key),
      position_in_buffer_(position_in_buffer),
      salt_counter_(salt_counter),
      buffer_(std::move(buffer)) {}

rlwe::StatusOr<std::unique_ptr<ChaChaPrng>> ChaChaPrng::Create(
    absl::string_view in_key) {
  if (in_key.length() != SeedLength()) {
    return absl::InvalidArgumentError(
        absl::StrCat("Cannot create Prng with key of the "
                     "wrong size. Real ",
                     "key length of ", in_key.length(), " instead of expected ",
                     "key length of ", SeedLength(), "."));
  }
  int position_in_buffer = 0;
  int salt_counter = 0;
  std::vector<Uint8> buffer;
  RLWE_RETURN_IF_ERROR(
      internal::ChaChaPrngResalt(in_key, internal::kChaChaOutputBytes,
                                 &salt_counter, &position_in_buffer, &buffer));
  return absl::WrapUnique<ChaChaPrng>(new ChaChaPrng(
      in_key, position_in_buffer, salt_counter, std::move(buffer)));
}

rlwe::StatusOr<Uint8> ChaChaPrng::Rand8() ABSL_LOCKS_EXCLUDED(mu_) {
  absl::MutexLock lock(&mu_);
  return internal::ChaChaPrngRand8(key_, &position_in_buffer_, &salt_counter_,
                                   &buffer_);
}

rlwe::StatusOr<Uint64> ChaChaPrng::Rand64() ABSL_LOCKS_EXCLUDED(mu_) {
  absl::MutexLock lock(&mu_);
  return internal::ChaChaPrngRand64(key_, &position_in_buffer_, &salt_counter_,
                                    &buffer_);
}

}  // namespace rlwe